Python网络与并发编程 02 TCP粘包

本文探讨了Python中TCP网络编程时遇到的粘包现象,分析了其产生的原因,包括TCP的流式传输特性及Nagle算法的影响。文章通过实例展示了手动拆分、预先发送消息长度以及使用json+struct增加消息头等解决粘包的方法,以确保数据的正确传输。
摘要由CSDN通过智能技术生成

TCP/Socket与subprocess

我们准备做一个可以在Client端远程执行Server端的shell命令并拿到其执行结果的程序,而涉及到网络通信就必然会使用到socket模块,此外还需要subprocess模块拿到命令执行结果。

关于传输层协议的选择我们采用TCP协议,因为它是可靠传输协议且一次传输的数据量要比UDP协议更大。

以下是Server端的代码实现:

import subprocess
from socket import *

# 默认直接实例化socket是IPV4 + TCP协议
server = socket()
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

server.bind(("localhost", 8888))
server.listen(5)

while 1:
    conn, clientAddr = server.accept()
    print("%s connect server" % clientAddr[0])
    
    while 1:
        try:
            command = conn.recv(1024)
            if not command:
                break

            result = subprocess.Popen(
                args=command.decode("u8"),
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )

            # get success result
            successOut = result.stdout.read()

            # get error result
            errorOut = result.stderr.read()

            # type == bytes
            dataBody = successOut or errorOut

            conn.send(dataBody)
        except ConnectionResetError as e:
            break

    print("%s close connect" % clientAddr[0])
    conn.close()

以下是Client端代码的实现:

from socket import *

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

while 1:
    command = input(">>>").strip()
    if not command:
        continue

    if command == "exit":
        break

    client.send(command.encode("u8"))
    dataBody = client.recv(1024)

    # windows server : decode("gbk")
    # unix server : decode("u8")
    print(dataBody.decode("u8"))

print("client close")
client.close()

使用测试,Client端输入命令:

>>>ls
__pycache__
socketClient.py
socketServer.py

>>>pwd
/Users/yunya/PythonProject

>>>cal
      六月 2021         
日 一 二 三 四 五 六  
       1  2  3  4  5  
 6  7  8  9 10 11 12  
13 14 15 16 17 18 19  
20 21 22 23 24 25 26  
27 28 29 30           
                      

>>>

粘包现象

上面的测试看起来一切都非常完美,但如果Client端输入一条结果很长的命令时会出现一次性读取不完的Bug,如下所示:

>>>info vim
File: *manpages*,  Node: vim,  Up: (dir)

VIM(1)                                                                  VIM(1)

NAME
       vim - Vi IMproved, a programmer's text editor

SYNOPSIS
       vim [options] [file ..]
       vim [options] -
       vim [options] -t tag
       vim [options] -q [errorfile]

       ex
       view
       gvim gview evim eview
       rvim rview rgvim rgview

DESCRIPTION
       Vim  is a text editor that is upwards compatible to Vi.  It can be used
       to edit all kinds of plain text.  It is especially useful  for  editing
       programs.

       There  are a lot of enhancements above Vi: multi level undo, multi win-
       dows and buffers, syntax highlighting, command line  edi
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值