socket_基础3_使用socket传输文件

前面两章记录了如何使用socket传输内存数据,下面就如何使用socket进行文件传输进行记录。下面代码实现了基础ftp功能,当前只实现了从client端使用“get filename”从客户端下载文件的功能,上传功能类似。其中对传输文件的md5值也进行了校验。

server端代码

 1 # _*_ coding:utf-8 _*_
 2 import socket,os,hashlib
 3 server = socket.socket() #创建连接描述符,默认使用iv4/tcp
 4 server.bind(("localhost",6969)) #指定监听地址和端口,开始等待客户端连接。
 5 server.listen(5) #监听
 6 print("服务端已启动")
 7 while True:
 8     conn,addr = server.accept() #创建和客户端交互数据的连接
 9     print('new conn',conn,addr)
10     while True:
11         type,filename = conn.recv(1024).decode().split() #1024为接收字节大小
12         print('get filename:',filename)
13         if len(filename) == 0:  #判断客户端是否断开,若客户端断开则接收端接收的数据长度为0
14             print("client is close")
15             break
16         elif os.path.isfile(filename): #判断客户端发送的文件请求是否存在
17             f = open(filename,'rb')
18             m = hashlib.md5()
19             conn.send(str( os.stat(filename).st_size).encode(encoding='utf-8')) #发送文件大小
20             conn.recv(1024)
21             for line in f:
22                 conn.send(line)
23                 m.update(line) #对文件进行md5运算
24             print('file md5:',m.hexdigest())
25             print( conn.recv(1024).decode())
26             conn.send(m.hexdigest().encode(encoding='utf-8')) #发送文件的md5值
27             f.close()
28         else:
29             print('file is not exit')
30             conn.send(b'file is not exit')
31             continue
32 
33 server.close()  #关闭连接

client端代码

 1 # _*_ coding:utf-8 _*_
 2 import socket,hashlib
 3 client = socket.socket() #创建连接描述符,指定socket连接的网络层和传输层协议,默认使用ipv4/tcp
 4 client.connect(("localhost",6969)) #使用连接描述符连接server,server信息以元组形式传入,包含ip地址和端口号
 5 while True:
 6     cmd = input("input your command,eg:get 'filename':")
 7     if len(cmd) == 0:
 8         continue
 9     client.send(cmd.encode(encoding='utf-8')) #发送hello world,send只能发送byte类型,不能发送字符串。encode默认会将字符串转为byte类型
10     file_size_tmp = client.recv(1024).decode() #接收服务端发送的文件大小/服务器端返回文件不存在
11     if file_size_tmp == 'file is not exit':
12         continue
13     else:
14         file_size = int(file_size_tmp)
15         print("file_size is:",file_size)
16         recv_size = 0
17         client.send(b'i have receive file_size') #为解决粘包问题,给服务端发送响应
18         f = open(cmd.split()[1] + '_new','wb')
19         m = hashlib.md5()
20         while recv_size < file_size:  #通过此循环持续收包
21             data=client.recv(1024)
22             f.write(data)
23             m.update(data)
24             recv_size += len(data)
25             print('recv_size:',recv_size)
26         client.send(b'Client have receive this file')
27         server_md5 = client.recv(1024).decode()
28         if server_md5 == m.hexdigest():  #校验接收和发送的文件md5值是否一样
29             print('this file get success')
30         else:
31             print('this file get faild,MD5 is not matched')
32             continue
33 
34 client.close()

猜你喜欢

转载自www.cnblogs.com/flags-blog/p/9571888.html