步骤:
创建TCP套接字:client_socket = socket(AF_INET,SOCK_STREAM)
配置监听8899接口:server_socket.bind(('ip地址',8899))
server_socket.listen(5)
链接ip地址:server_socket.bind(('ip地址',8899))
接收:client_socket, client_info = server_socket.accept()
客户端:
import socket # 导入 socket 模块,用于创建网络套接字和进行网络通信
import os # 导入 os 模块,用于处理文件路径和操作系统相关的功能
import sys # 导入 sys 模块,用于与 Python 解释器进行交互和获取系统相关信息
import struct # 导入 struct 模块,用于处理二进制数据的打包和解包
# 创建一个 TCP 客户端套接字,连接到指定的服务器主机和端口
def sock_client_image():
while True: # 无限循环,用于不断发送文件数据
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建一个基于 IPv4 和 TCP 协议的套接字对象
s.connect(('192.168.8.55', 6789)) # 连接到指定的服务器主机和端口
except socket.error as msg:
print(msg)
print(sys.exit(1)) # 如果发生错误,打印错误消息,然后退出程序
filepath = input('input the file:') # 用户输入要发送的文件路径
fhead = struct.pack(b'128sq', bytes(os.path.basename(filepath), encoding='utf8'),
os.stat(filepath).st_size) # 创建文件名和文件大小的数据包
s.send(fhead) # 发送文件名和文件大小的数据包
fp = open(filepath, 'rb') # 以二进制读取模式打开文件
while True: # 循环读取文件数据并发送
data = fp.read(1024) # 读取 1024 字节的文件数据
if not data: # 如果读取到文件末尾
print('{0} send over...'.format(filepath)) # 打印发送完成的提示信息
break # 结束文件发送循环
s.send(data) # 发送文件数据
s.close() # 关闭套接字连接
if __name__ == '__main__':
sock_client_image() # 调用 sock_client_image 函数,启动文件发送客户端
服务端:
import socket # 导入 socket 模块,用于创建网络套接字和进行网络通信
import os # 导入 os 模块,用于处理文件路径和操作系统相关的功能
import sys # 导入 sys 模块,用于与 Python 解释器进行交互和获取系统相关信息
import struct # 导入 struct 模块,用于处理二进制数据的打包和解包
# 创建并监听一个 TCP 服务器套接字
def socket_service_image():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建一个基于 IPv4 和 TCP 协议的套接字对象
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置套接字选项,允许地址重用
s.bind(('192.168.8.177', 6789)) # 将套接字绑定到指定的主机和端口
s.listen(10) # 开始监听传入的连接请求,最多允许 10 个排队的连接
except socket.error as msg:
print(msg)
sys.exit(1)
print('Wait for Connection.....................') # 打印等待连接的提示信息
while True: # 无限循环,用于接受连接和处理数据
sock, addr = s.accept() # 接受客户端的连接请求,并返回一个新的套接字对象和客户端地址
deal_image(sock, addr) # 调用 deal_image 函数来处理接收到的文件数据
# 处理接收到的文件数据
def deal_image(sock, addr):
print("Accept connection from {0}".format(addr)) # 打印接受连接的提示信息
while True: # 无限循环,用于接收文件数据
fileinfo_size = struct.calcsize('128sq') # 计算文件名和文件大小的数据包大小
buf = sock.recv(fileinfo_size) # 接收文件名和文件大小的数据包
if buf: # 如果接收到数据包
filename, filesize = struct.unpack('128sq', buf) # 解包得到文件名和文件大小
fn = filename.decode().strip('\x00') # 解码文件名,并去除末尾的空字符
new_filename = os.path.join('./', 'new_'+fn) # 构造新的文件名
recvd_size = 0 # 初始化已接收的文件数据大小为 0
fp = open(new_filename, 'wb') # 以二进制写入模式打开文件
while not recvd_size == filesize: # 如果接收的文件数据大小不等于文件大小
if filesize - recvd_size > 1024: # 如果剩余的文件数据大于 1024 字节
data = sock.recv(1024) # 接收 1024 字节的文件数据
recvd_size += len(data) # 更新已接收的文件数据大小
else:
data = sock.recv(1024) # 接收剩余的文件数据
recvd_size = filesize # 更新已接收的文件数据大小为文件大小
fp.write(data) # 将接收到的文件数据写入文件
fp.close() # 关闭文件
sock.close() # 关闭套接字连接
break # 结束当前文件数据处理
if __name__ == '__main__':
socket_service_image() # 调用 socket_service_image 函数,启动文件传输服务