组合要发送的Python TCP包

dzjeubhm  于 2023-01-24  发布在  Python
关注(0)|答案(1)|浏览(128)

我尝试使用Python中的套接字发送TCP数据包,并且我可以成功地将数据包发送到外部,我可以使用WireShark看到它们。但是,正如您所看到的,在while循环中,代码等待输入ENTER键以发送数据包。当我逐个按Enter键时,我可以看到我的数据(字节数组格式,以0xEFEB000000开头的18个字节),从文件中读取,但由于我认为没有必要且容易混淆,因此未在此处给出,按我的要求逐包发送。但是,当我按住ENTER按钮时,它连续发送数据包的速度比一个接一个快得多。在这种情况下,我可以在WireShark中看到一些数据被合并到一个TCP数据包中。我不希望这样,不幸的是,这是非常严格的。我如何才能强制socket逐个数据包单独发送我给的有效负载?
从套接字导入套接字、AF_INET、SOCK_STREAM

if __name__ == "__main__":
    CLIENT_SOCK = socket(AF_INET, SOCK_STREAM)
    CLIENT_SOCK.connect(("192.168.1.10", 42000))
 
    while True:
        input("Press ENTER to send a TCP packet...")
        # some file IO here to construct data variable,
        # 18 byte bytearray format. starts with 0xEFEB000000
        CLIENT_SOCK.sendall(data)

具有单个有效负载的单个数据包

组合5个有效载荷的单个数据包

gfttwv5a

gfttwv5a1#

TCP不是基于消息的。它只是返回按发送顺序写入套接字的字节,但由于网络缓冲区可以将字节分解为它选择的任何数据包。将接收方 Package 在一个socket.makefile对象中,该对象将缓冲读取的数据,然后.read(n)将准确读取 n 字节,除非套接字提前关闭。例如:
server.py

import socket

s = socket.socket()
s.bind(('', 5000))
s.listen()
c, a = s.accept()

# 'with' will close the client socket and makefile object
# when it exits.
with c, c.makefile('rb') as f:
    while True:
        data = f.read(18)
        if not data:
            break
        print(data)

client.py

import socket

s = socket.socket()
s.connect(('localhost', 5000))
s.sendall(b'abcdefghijklmnopqr')
s.sendall(b'abc')
s.sendall(b'defghijklm')
s.sendall(b'nopqr')
s.sendall(b'abcdefghijklm')
s.sendall(b'nopqrabcdefghijklm')
s.sendall(b'nopqr')
s.close()

服务器输出:

b'abcdefghijklmnopqr'
b'abcdefghijklmnopqr'
b'abcdefghijklmnopqr'
b'abcdefghijklmnopqr'

注:这 * 可能 * 看起来与直接c.recv(18)一起工作,但在忙碌/复杂的网络环境中每次可能无法接收18字节。

相关问题