我有简单的TCP套接字程序,我想以10个字节的块发送字符串.服务器将加入块.但是我不确定如何将字符串拆分为二进制文件以及如何发送二进制文件块.我不想一次发送512个字节,而是多次发送10个字节.
我找到了一个可以将数据序列化为字节串(?)的模块Pickle,但是如何对此应用socket.send()?
服务器:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", my_port))
server_socket.listen(5)
client_socket, address = server_socket.accept()
data = client_socket.recv(512)
Run Code Online (Sandbox Code Playgroud)
客户:
message = "some string I want to send in chunks"
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, my_port))
client_socket.send(message)
client_socket.close()
Run Code Online (Sandbox Code Playgroud)
首先,您的代码实际上不是一次发送 512个字节,它一次接收 512个字节.
现在,我认为你真的在问两个问题.
socket.SOCK_STREAM
)让我们回答2.首先:如果在字节字符串上调用socket.send,它应该以二进制形式作为TCP有效负载发送出去.
对于1.,最简单的方法是将数据拆分为块(现在你知道你在字符串上操作,你可以使用切片操作简单地做到这一点(参见关于字符串的Python教程 - 例如s[0:10]
,s[10:20]
等等). ,你需要确保这些切片是单独发送的.这可以通过调用来完成socket.send
,但问题是,你的TCP/IP堆栈可能会将这些组合成数据包,即使你不想要它 - 你毕竟问了它为你提供一个流套接字,socket.SOCK_STREAM
如果你正在写一个文件,你在这种情况下要做的就是刷新文件,但对于Python套接字来说这似乎并不容易(参见这个问题).
现在,我认为这个问题的答案,说这是不可能的,是不对的.似乎Scapy会让你发送10个字节的TCP块(我从这里得到了chunks()函数).我在wireshark中检查了它,并尝试了多次,结果一致,但我没有检查实现,以确保确保发生这种情况.
您可能应该问自己为什么要以10个字节的块发送数据,而不是让TCP处理它的设计目的,并考虑使用分隔符.
无论如何,这里是使用Scapy的代码(有趣的事实:它看起来像运行它不需要root权限):
客户:
from scapy.all import *
import socket
host = '192.168.0.x' #replace with your IP
my_port = 3002
message = "some string I want to send in chunks"
def chunks(lst, n):
"Yield successive n-sized chunks from lst"
for i in xrange(0, len(lst), n):
yield lst[i:i+n]
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, my_port))
ss=StreamSocket(client_socket,Raw)
for chunk in chunks(message, 10):
print "sending: " + chunk
ss.send(Raw(chunk) )
client_socket.close()
Run Code Online (Sandbox Code Playgroud)
服务器:
import socket
my_port=3002
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", my_port))
server_socket.listen(5)
client_socket, address = server_socket.accept()
while (True):
data = client_socket.recv(512)
if (data):
print data
else:
break
Run Code Online (Sandbox Code Playgroud)