Python套接字 - 以10个字节的块发送字符串

时间:2012-11-22 17:02:30

标签: python sockets

我有简单的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)

客户端:

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()

1 个答案:

答案 0 :(得分:7)

首先,您的代码实际上并非一共发送 512个字节,它一次接收 512个字节。

现在,我认为你真的在问两个问题。

  1. 如何通过TCP连接一次发送10个字节(您正在使用socket.SOCK_STREAM
  2. 如何使用Python套接字发送原始字节。
  3. 让我们回答2.首先:如果你在字节字符串上调用socket.send,它应该以二进制形式作为TCP有效负载发送。

    对于1.,最简单的方法是将数据拆分为块(现在你知道你正在对字符串进行操作,你可以使用切片操作来做到这一点(参见Python tutorial on strings - 例如{ {1}},s[0:10]等。接下来,您需要确保单独发送这些切片。这可以通过调用s[10:20]来完成,但问题是,您的TCP / IP堆栈可能会分组即使你不想要它们也会成为数据包 - 你毕竟要求它为你提供一个套接字,socket.send。如果你正在写一个文件,你是什么的在这种情况下你要刷新文件,但对于Python套接字来说这似乎并不容易(参见this question)。

    现在,我认为这个问题的答案,说这是不可能的,是不对的。似乎Scapy将允许您发送10个字节的TCP块(我从here获得了chunks()函数)。我在wireshark中检查了它,并尝试了多次,结果一致,但我没有检查实现,以确保确保发生这种情况。

    您应该问自己为什么要以10个字节的块发送数据,而不是让TCP处理它的设计目的,并考虑使用分隔符。

    无论如何,这里是使用Scapy的代码(有趣的事实:它看起来像运行它不需要root权限):

    客户端:

    socket.SOCK_STREAM

    服务器:

    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()