14.socket - TCP粘包

粘包产生的原因:

1.因为TCP优化算法,如果客户端一次发送数据过小,会导致多次数据合并成一个大包一起发送给服务端
2.如果客户端发送数据过大,会导致数据拆分成多个包,分多次发送给服务端

粘包解决:

服务端:

#low版解决粘包版本
# from socket import *
# import subprocess
# ip_port=('127.0.0.1',8080)
# back_log=5
# buffer_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()
#     print('新的客户端链接',addr)
#     while True:
#         #收
#         try:
#             cmd=conn.recv(buffer_size)
#             if not cmd:break
#             print('收到客户端的命令',cmd)
#
#             #执行命令,得到命令的运行结果cmd_res
#             res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
#                                  stderr=subprocess.PIPE,
#                                  stdout=subprocess.PIPE,
#                                  stdin=subprocess.PIPE)
#             err=res.stderr.read()
#             if err:
#                 cmd_res=err
#             else:
#                 cmd_res=res.stdout.read()
#
#             #发
#             if not cmd_res:
#                 cmd_res='执行成功'.encode('gbk')
#
#             length=len(cmd_res)
#             conn.send(str(length).encode('utf-8'))
#             client_ready=conn.recv(buffer_size)
#             if client_ready == b'ready':
#                 conn.send(cmd_res)
#         except Exception as e:
#             print(e)
#             break



from socket import *
import subprocess
import struct
ip_port=('127.0.0.1',8080)
back_log=5
buffer_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()
    print('新的客户端链接',addr)
    while True:
        #收
        try:
            cmd=conn.recv(buffer_size)
            if not cmd:break
            print('收到客户端的命令',cmd)

            #执行命令,得到命令的运行结果cmd_res
            res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                                 stderr=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stdin=subprocess.PIPE)
            err=res.stderr.read()
            if err:
                cmd_res=err
            else:
                cmd_res=res.stdout.read()

            #发
            if not cmd_res:
                cmd_res='执行成功'.encode('gbk')

            length=len(cmd_res)

            data_length=struct.pack('i',length)
            conn.send(data_length)
            conn.send(cmd_res)
        except Exception as e:
            print(e)
            break


客户端解决:

#low版解决粘包版
# from socket import *
# ip_port=('127.0.0.1',8080)
# back_log=5
# buffer_size=1024
#
# tcp_client=socket(AF_INET,SOCK_STREAM)
# tcp_client.connect(ip_port)
#
# while True:
#     cmd=input('>>: ').strip()
#     if not cmd:continue
#     if cmd == 'quit':break
#
#     tcp_client.send(cmd.encode('utf-8'))
#
#
#     #解决粘包
#     length=tcp_client.recv(buffer_size)
#     tcp_client.send(b'ready')
#
#     length=int(length.decode('utf-8'))
#
#     recv_size=0
#     recv_msg=b''
#     while recv_size < length:
#         recv_msg += tcp_client.recv(buffer_size)
#         recv_size=len(recv_msg) #1024
#
#
#     print('命令的执行结果是 ',recv_msg.decode('gbk'))
# tcp_client.close()


from socket import *
import struct
from functools import partial
ip_port=('127.0.0.1',8080)
back_log=5
buffer_size=1024

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

while True:
    cmd=input('>>: ').strip()
    if not cmd:continue
    if cmd == 'quit':break

    tcp_client.send(cmd.encode('utf-8'))


    #解决粘包
    length_data=tcp_client.recv(4)
    length=struct.unpack('i',length_data)[0]

    recv_msg=''.join(iter(partial(tcp_client.recv, buffer_size), b''))


    print('命令的执行结果是 ',recv_msg.decode('gbk'))
tcp_client.close()
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本文主要通过整理网络上的资料,整理出的关于TCP方面的简单理论知识。作为Java程序员虽然更多的时候我们都是直接调...
    tomas家的小拨浪鼓阅读 11,029评论 1 100
  • 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的。因此TCP的socket编程,收发两端(客户...
    树根曰阅读 11,211评论 1 16
  • 计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。 按照计算机网络的定义,通过一定...
    蛋炒饭_By阅读 5,028评论 0 10
  • 目录: TCP是什么TCP报文结构TCP连接过程TCP状态转移TCP流量控制 —— 滑动窗口TCP拥塞控制TCP可...
    Katou_Megumi阅读 5,229评论 0 4
  • 小黑 文/宇 小黑是外婆家的一条狗。它是别人家的母狗生下来的小狗,外婆在它几个月时把它抱了回来,养在了家里。 小黑...
    我们娘仨阅读 3,047评论 0 3

友情链接更多精彩内容