网络编程: 1, 简单版的 上传 与 下载; 2, 简单升级版的 上传 与 下载( 有详细注释)
ps: 下面两个版本全部是 基于 tcp协议完成的.
简单版:
服务器(server)代码:
因为是简单版的所以 无注释
1 from socket import socket 2 sk = socket() 3 sk.bind(('127.0.0.1', 8585)) 4 sk.listen() 5 6 def display(): return '1, 上传\n2, 下载' 7 8 9 def upload(word,chose_path): 10 # chose_path = input('>>>请输入要上传的文件路径:') 11 with open(chose_path.decode('utf-8'), 'wb') as f: 12 f.write(word) 13 14 15 def download(): 16 name = '__init__.py' 17 with open(name, 'rb') as f: 18 word = f.read() 19 return name.encode('utf-8'), word 20 21 22 def main(): 23 while 1: 24 conn, addr = sk.accept() 25 while 1: 26 conn.send(display().encode('utf-8')) 27 msg_r = conn.recv(1024).decode('utf-8') 28 if msg_r == 'q':continue 29 if msg_r == '1': 30 word = conn.recv(1024*10) 31 chose_path = conn.recv(1024 * 10) 32 upload(word, chose_path) 33 conn.send('上传成功'.encode('utf-8')) 34 elif msg_r == '2': 35 name, word = download() 36 conn.send(name) 37 conn.send(word) 38 39 main()
客户端(client) 代码:
1 from socket import socket 2 3 sk = socket() 4 sk.connect(('127.0.0.1', 8585)) 5 flag = True 6 7 def upload(): 8 chose_path = input('>>>请输入要上传的文件路径:') 9 with open(chose_path, 'rb') as f: 10 word = f.read() 11 return chose_path.encode('utf-8'), word 12 13 14 def download(name, word): 15 with open(name,'wb') as f: 16 f.write(word) 17 return '下载成功' 18 19 20 def main(): 21 global flag 22 msg_r = sk.recv(1024).decode('utf-8') 23 print(msg_r) 24 choise = input('>>>请选择功能ID(输入"q"退出程序):').strip().encode('utf-8') 25 sk.send(choise) 26 if choise == 'q'.encode('utf-8'): flag = False 27 if choise == '1'.encode('utf-8'): 28 chose_path, word = upload() 29 sk.send(word) 30 sk.send(chose_path) 31 print(sk.recv(1024).decode('utf-8')) 32 elif choise == '2'.encode('utf-8'): 33 name = sk.recv(1024).decode('utf-8') 34 word = sk.recv(1024) 35 print(download(name, word)) 36 37 while flag: 38 main() 39 sk.close()
简单的 升级版 的上传与下载:
服务器(server):
有详细注释: 此程序会出现个别粘包现象
1 from socket import socket 2 import os 3 import pickle 4 5 sk = socket() 6 sk.bind(('127.0.0.1', 8589)) 7 sk.listen() 8 9 def display(): return '1, 上传\n2, 下载' # 此函数用来发送第一个选择 10 11 12 def update(name): # 更名 13 chose = conn.recv(1024).decode('utf-8') # 接收客户的选择 14 if chose == '1':pass # 如果选择 1 覆盖 则不用操作 15 elif chose == '2': # 如果选择 2 更改 接收客户端的消息 16 name = conn.recv(1024).decode('utf-8') # 新文件的名字 17 return name 18 19 20 def upload(word,chose_path): # 上传函数 21 chose_path = chose_path.decode('utf-8') # 把接收的文件名 解码 22 23 # 判断 该文件 是否已经存在与 服务器 当前工作目录下: 24 if chose_path in os.listdir('E:/老男孩工具/13期课后作业及视频/day33/myself_test/new_upload_download/updata_server_path'): # 路径 按照自己的文件夹来自定义 25 # 如果在, 向客户端发消息, 并且询问 用户的选择 26 conn.send('服务器已存在该文件:选择覆盖还是更名:\n1, 覆盖\n2, 更名'.encode('utf-8')) 27 name = update(chose_path) # 调用 update() 更改函数 获得新文件的名字 或 老文件的名字 28 if not name:chose_path = name # 如果 name 不为None 给文件进行改名: 29 with open(chose_path, 'wb') as f: # 打开文件 进行写入 30 f.write(word) 31 32 33 def download(): # 下载 34 # 把服务器工作目录下 所有文件 装到列表里 35 path_list = os.listdir(r'E:\老男孩工具\13期课后作业及视频\day33\myself_test\new_upload_download\updata_server_path') 36 lis = [{x:y} for x,y in enumerate(path_list,1)] # 生成一个 有序的元素为字典的 内容列表 37 pic = pickle.dumps(lis) # 序列化一下 38 conn.send(pic) # 发送给 客户端, 然后询问 客户要下载那个文件的id 39 file_id = conn.recv(1024).decode('utf-8') # 接收到 id 40 name = lis[int(file_id)-1][int(file_id)] # 取得 相对应的文件名 41 with open(name, 'rb') as f: # 打开文件, 读到内容 42 word = f.read() 43 return name.encode('utf-8'), word # 返回文件名字, 和 内容 44 45 46 def main(): ## 服务器 47 while 1: 48 conn.send(display().encode('utf-8')) # 发送 第一条消息: '1, 上传\n2, 下载' 49 msg_r = conn.recv(1024).decode('utf-8') # 接收 客户端的选择信息 50 if msg_r == 'q':break # 如果是q 退出程序 51 if msg_r == '1': # 如果 选择 1 此时需要在客户端 向用户索要 文件信息. 52 word = conn.recv(1024*10) # 接收 文件内容 53 chose_path = conn.recv(1024 * 10) # 接收文件名字 54 upload(word, chose_path) # 调用上传 函数 并且把文件内容 和名字 传进去 55 conn.send('上传成功'.encode('utf-8')) # 如果程序成功运行到了这里 就把消息发过去. 56 elif msg_r == '2': # 如果选择2 下载 57 name, word = download() # 调用 下载函数 download() 把返回值 分别 赋值 name, word 58 conn.send(name) # 发送 文件名字. 59 conn.send(word) # 最后一条消息: 文件内容 60 return 61 62 63 if __name__ == '__main__': 64 while 1: 65 conn, addr = sk.accept() 66 main() 67 conn.close()
客户端(client):
同样 有详细的注释:
1 import pickle 2 from socket import socket 3 import os 4 5 sk = socket() 6 sk.connect(('127.0.0.1', 8589)) 7 flag = True 8 9 def upload(): 10 chose_path = input('>>>请输入要上传的文件路径:') 11 with open(chose_path, 'rb') as f: 12 word = f.read() # 读取文件内容 13 chose_path = os.path.basename(chose_path) # 取得 路径的 文件名 14 return chose_path.encode('utf-8'), word # 把word name 返回 15 16 17 def download(name, word): 18 path = input('>>>请选择工作路径:') 19 new_path = os.path.join(path, name) 20 with open(new_path,'wb') as f: 21 f.write(word) 22 return '下载成功' 23 24 25 def update(): # 更名 26 chose = input('>>>请输入您的选择:').strip().encode('utf-8') 27 sk.send(chose) # 把选择发给 服务器, 让服务器做判断 28 if chose == '1'.encode('utf-8'):pass # 如果是1 则不作任何操作 29 elif chose == '2'.encode('utf-8'): # 如果是2 则更名 30 new_name = input('>>>请输入新的名字:').encode('utf-8') 31 sk.send(new_name) # 把新名字 给服务器 发过去 32 print(sk.recv(1024).decode('utf-8')) # 接收 服务器 发送的 成功的消息 并且打印出来 33 34 35 def main(): # 客户端 36 global flag 37 msg_r = sk.recv(1024).decode('utf-8') # 接收第一条消息, '1, 上传\n2, 下载' 38 print(msg_r) 39 choise = input('>>>请选择功能ID(输入"q"退出程序):').strip().encode('utf-8') 40 sk.send(choise) # 把 客户选择的功能发送给 服务器 41 if choise == 'q'.encode('utf-8'): flag = False 42 if choise == '1'.encode('utf-8'): 43 chose_path, word = upload() # 调用upload() 上传函数 返回 word 和 文件名 44 sk.send(word) # 把 word发送给服务器 45 sk.send(chose_path) # 把文件名发送给 服务器 46 ret = sk.recv(1024).decode('utf-8') # 接收 服务器传输过来的 判断是否 存在的语句 47 print(ret) 48 if ret == '服务器已存在该文件:选择覆盖还是更名:\n1, 覆盖\n2, 更名': # 如果是这句话就 调用下面的函数, 如果不是这句话 会打印 上传成功 49 update() # 此函数的功能 和 服务器里面的 功能一样 :更名 50 51 elif choise == '2'.encode('utf-8'): # 当选择 2 下载 时 52 pic = pickle.loads(sk.recv(1024)) # 把服务器发来的 pickle 字典 反序列化了 53 print('下面是所有子文件:') 54 for i in pic: 55 print(i) # 一个一个打印出来 56 file_id = input('>>>请输入想要下载的文件的ID:').strip().encode('utf-8') 57 sk.send(file_id) # 把 id 发给 服务器 58 name = sk.recv(1024).decode('utf-8') # 接收 服务器发来的 文件的名字 59 word = sk.recv(1024*1000) # 最后一条消息: 接收文件名 60 download(name, word) # 此函数 是用来把内容写入新文件 61 print('下载成功') 62 63 64 if __name__ == '__main__': 65 while flag: 66 main() 67 sk.close()