接收端(server)代码
import os
import struct
import socket
import threading
##########
def deal_data(conn, addr):
# 打印client地址
print('')
print('>> Accept connection from {0}'.format(addr[0]))
# 接收文件头信息
buf = conn.recv(struct.calcsize('128sl')) # conn.recv(132)
filename, filesize = struct.unpack('128sl', buf)
filename = filename.decode().strip('\00')
new_filename = 'new_' + filename
print('>> File name: {0}'.format(new_filename))
print('>> File size: {0}'.format(filesize))
# 接收文件内容
recvd_size = 0 # 定义已接收文件的大小
file_content = open(new_filename, 'wb')
print('>> Transfer begins')
while recvd_size != filesize:
if filesize - recvd_size > 1024:
data = conn.recv(1024)
recvd_size = recvd_size + len(data) # 注意:len(data)不一定为1024
else:
data = conn.recv(filesize - recvd_size)
recvd_size = filesize
file_content.write(data)
file_content.close()
print ('>> Transfer ends')
# 断开连接
conn.close()
##########
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('30.0.0.3', 12345))
s.listen(10)
print('---- Waiting for connection')
while True:
conn, addr = s.accept()
t = threading.Thread(target=deal_data, args=(conn, addr))
t.start()
发送端(client)代码
import os
import socket
import struct
while True:
# 建立connection
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('30.0.0.3', 12345))
print('---- Connected')
# 发送文件
filepath = input('>> Input the file path: ')
if os.path.isfile(filepath):
# 发送文件头,包含文件名(128bytes)和文件大小(integer)信息
filename = os.path.basename(filepath).encode()
filesize = os.path.getsize(filepath)
file_head = struct.pack('128sl', filename, filesize)
s.send(file_head)
# 发送文件内容
file_content = open(filepath, 'rb')
print('>> Transfer begins')
while True:
data = file_content.read(1024)
if not data:
print('>> Transfer ends\n')
break
s.send(data)
file_content.close()
# 监测connection是否关闭
while True:
b = s.recv(5) # bytes
a = b.decode() # string
# 当接收端断开connection时,会发送空字符串
if not b: break