Python网络编程socket模块实例解析(3)

那么怎么解决粘包问题呢,通过发送以及接收确认包,还是以上面的例子说明,客户在发送文件大小之后不要马上发送文件,先recv接收一下,等待服务器发送已收到文件大小的确认包之后,再读取文件、发送文件,这样文件的发送和之前数据的发送就
完全独立开来了。

#服务器端
import socket
sk= socket.socket()
 
sk.bind(('127.0.0.1',9999,))#绑定IP和端口,以一个元组的方式传进去
sk.listen(5)#在前面链接已经建立的情况下,后面最多让五个人等待
while True:#
    conn,address= sk.accept()
    conn.sendall(bytes('链接已建立,可以发送数据了',encoding='utf-8'))
 
    file_size = str(conn.recv(1024),encoding='utf-8')#接收文件大小
    print('接收的文件字节数:'+file_size)
    total_size = int(file_size)
    has_recv = 0#默认已接收了0个字节
    conn.sendall(bytes('文件大小已收到,可以开始发送数据了',encoding='utf-8'))#解决粘包问题,已经收到了文件大小,后面就可以单独发文件了
    f = open('linuxidc.com.png','wb')
    #先接收文件大小,再开始接收文件
 
    while True:
        if total_size ==has_recv:#如果已接收的文件大小与客户端发送的一样大,则表示已经接收完毕
            break
 
        data = conn.recv(1024)
 
        f.write(data)
        has_recv +=len(data)
    print('文件接收成功')
    f.close()

下面是客户端

#客户端
import os
import socket
obj =socket.socket()
 
obj.connect(('127.0.0.1',9999,))#链接服务端
'''
客户端去链接服务端,如果服务器端没有返回消息给客户端,则客户端会一直
在recv状态,一直等待服务器的消息
# '''
#obj.sendall(bytes('你好',encoding='utf-8'))
ret_bytes = obj.recv(1024)
ret_str = str(ret_bytes,encoding='utf-8')
print(ret_str)
 
#发送文件大小
size=os.stat('linuxidc.png').st_size#获取文件大小
obj.sendall(bytes(str(size),encoding='utf-8'),)#文件大小的int型,要先转化为字符串
ack_packet=obj.recv(1024)
print(str(ack_packet,encoding='utf-8'))
with open('linuxidc.png','rb')as f:
    for line in f:
        obj.sendall(line)
obj.close()

Python网络编程socket模块实例解析

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e028acd425ae935b68683782556bb839.html