粘包解决方法

版权声明:17602128911 https://blog.csdn.net/bus_lupe/article/details/86568693

tcp_server
设置每次接收数据的大小

from socket import *

ip_port = ('127.0.0.1', 8081)
back_log = 5

tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

conn, addr = tcp_server.accept()

data1 = conn.recv(5)
print(data1)
data2 = conn.recv(5)
print(data2)
data3 = conn.recv(4)
print(data3)

conn.close()
tcp_server.close()

tcp_client

from socket import *

ip_port = ('127.0.0.1', 8081)

tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)

tcp_client.send('hello'.encode(encoding='utf-8'))
tcp_client.send('world'.encode(encoding='utf-8'))
tcp_client.send('lupe'.encode(encoding='utf-8'))

tcp_client.close()

粘包2,发送量大于接收量
tcp_server

from socket import *

ip_port = ('127.0.0.1', 8081)
back_log = 5

tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

conn, addr = tcp_server.accept()

data1 = conn.recv(1)
print(data1)
data2 = conn.recv(5)
print(data2)
data3 = conn.recv(1)
print(data3)

conn.close()
tcp_server.close()

tcp_client

from socket import *

ip_port = ('127.0.0.1', 8081)

tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)

tcp_client.send('helloworldlupe'.encode(encoding='utf-8'))

tcp_client.close()

udp不会粘包
udp_server

from socket import *

ip_port = ('127.0.0.1', 8081)

udp_server = socket(AF_INET, SOCK_DGRAM)
udp_server.bind(ip_port)

data1, addr = udp_server.recvfrom(1024)
print(data1)
data2, addr = udp_server.recvfrom(1024)
print(data2)
data3, addr = udp_server.recvfrom(104)
print(data3)

udp_server.close()

udp_client

from socket import *

ip_port = ('127.0.0.1', 8081)

udp_client = socket(AF_INET, SOCK_DGRAM)

udp_client.sendto(b'hello', ip_port)
udp_client.sendto(b'world', ip_port)
udp_client.sendto(b'lupe', ip_port)

udp_client.close()

解决粘包

tcp_server

from socket import *
# 执行字符串格式的cmd命令
import subprocess
# 将数据长度打包成四位二进制
import struct

# ip地址加端口标识电脑上的一个程序
ip_port = ('127.0.0.1', 8082)
# 最大连接数
back_log = 5
buf_size = 1024

tcp_server = socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

while True:
    conn, addr = tcp_server.accept()
    while True:
        # try except在客户端异常退出处理错误,防止服务端异常退出
        try:
            cmd = conn.recv(buf_size)
            # 执行cmd命令接收执行结果
            cmd_res = subprocess.Popen(cmd.decode(encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
            # 在客户端主动退出做处理,防止循环recev空
            if not cmd: break
            err = cmd_res.stderr.read()
            if err:
                res = err
            else:
                res = cmd_res.stdout.read()

            if not res:
                res = '执行成功'.encode(encoding='gbk')
            # 把将要发送的数据打包成四位二进制
            length = struct.pack('i', len(res))
            # 发送数据长度
            conn.send(length)
            # 发送内容
            conn.send(res)
        except Exception as err:
            print(err)
            break

tcp_server.close()

tcp_client

from socket import *
import struct

ip_port = ('127.0.0.1', 8082)
buf_size = 1024

tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)

while True:
    msg = input('>>').strip()
    if not msg: continue
    if msg == 'quit': break
    tcp_client.send(msg.encode(encoding='utf-8'))
    # 接收四位数据长度信息
    data_length = tcp_client.recv(4)
    length = struct.unpack('i', data_length)[0]
    msg_size = 0
    # 比较长度的时候用二进制而不是字符串
    res_msg = b''
    # 接收内容
    while msg_size < length:
        res_msg += tcp_client.recv(buf_size)
        msg_size = len(res_msg)
    print(res_msg.decode(encoding='gbk'))
tcp_client.close()

iter补充

arr = ['a', 'b', 'c', 'd']

def test():
    return arr.pop()

# 生成遍历器,遇到b停止
l = iter(test, 'b')
print(l.__next__())
print(l.__next__())
print(l.__next__())
'''
Traceback (most recent call last):
d
c
  File "C:/py/test/day30/tcp_shell_client.py", line 82, in <module>
    print(l.__next__())
StopIteration
'''

偏函数

from functools import partial

def add(x, y):
    return x + y
# 偏函数,第一个参数是函数,第二个参数接收一个固定值
test = partial(add, 1)
print(test(2)) # 3
print(test(9)) # 10

猜你喜欢

转载自blog.csdn.net/bus_lupe/article/details/86568693
今日推荐