socket粘包

只有TCP会出现粘包,UDP不会。

引发粘包的两种场景:

1、发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,会合到一起,产生粘包)

2、接收方不及时接收缓冲区的包,造成多个包接收(服务端发送了一段数据,客户端只收了一小部分,客户端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

解决第一种场景的粘包(连续发送数据时,利用recv阻塞,等待客户端响应再继续发送)

服务端

#coding=utf-8

import socket
import os

server = socket.socket()
server.bind(('localhost', 8888))
server.listen(5)

while True:
    conn, address = server.accept()
    while True:
        rev = conn.recv(1024)
        if len(rev) == 0: break
        rev = os.popen(rev).read()
        conn.send(str(len(rev)))
        prompt_again = conn.recv(1024)  # 等待客户端响应
        print rev
        conn.send(rev or 'ok!')  # 继续发消息
    conn.close()

客户端(收到消息后,发送消息,通知服务端可以继续发送)

#coding=utf-8

import socket

client = socket.socket()
client.connect(('localhost', 8888))

while True:
    msg = raw_input('>>')
    if len(msg.strip()) == 0: continue
    client.send(msg)
    rev_len = client.recv(1024)
    print '服务器端消息长度:', rev_len
    client.send('again')  # 通知服务器端可以继续发送
    rev = client.recv(1024)
    print rev

client.close()

解决第二种场景的粘包(服务器端在发送大量数据之前,先发送长度,客户端循环接收直至总数据长度不小于服务器端发送的长度值)

 服务端

#coding=utf-8

import socket
import os

server = socket.socket()
server.bind(('localhost', 9999))
server.listen(5)

while True:
    conn, address = server.accept()
    while True:
        rev = conn.recv(1024)
        if len(rev) == 0: break
        if os.path.isfile(rev):
            size = os.stat(rev).st_size
            conn.send(str(size))
            prompt_again = conn.recv(1024)
            f = open(rev)
            for line in f:
                conn.send(line)
            f.close()
    conn.close()

客户端

#coding=utf-8

import socket

client = socket.socket()
client.connect(('localhost', 9999))

while True:
    file_name = raw_input('>>')
    if len(file_name.strip()) == 0: continue
    client.send(file_name)
    rev_len = int(client.recv(1024))
    client.send('again')
    len_now = 0
    f = open(file_name + 'tmp', 'w')
    while len_now < rev_len:
        data = client.recv(1024)
        len_now += len(data)
        f.write(data)
    f.close()
client.close()
原文地址:https://www.cnblogs.com/allenzhang-920/p/9626339.html