2012-11-22 47 views
1

我有简单的tcp套接字程序,我想以10个字节为单位发送字符串。服务器将加入这些块。 但是我不知道如何将字符串拆分为二进制文件以及如何发送二进制文件块。我不想一次发送512个字节,而是想多次发送10个字节。Python套接字 - 以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() 
+2

'消息'在Python 2中已经是一个字节串了。[要在块中进行迭代,请参阅此文档](http://stackoverflow.com/a/434328/4279)。为什么你只需要发送块就可以立即在服务器上加入?看起来像[XY问题](http://www.perlmonks.org/index.pl?node_id=542341)。 – jfs

回答

7

首先,你的代码是在同一时间实际上并不发送 512字节,这是在同一时间接收 512字节。

现在,我想你真的问了两个问题。

  1. 你如何在同一时间通过TCP连接发送10个字节(使用的是socket.SOCK_STREAM
  2. 你如何发送邮件使用Python的插座原始字节。

让我们回答2.首先:如果您在字节字符串上调用socket.send,它应该以二进制形式作为TCP有效负载发送出去。

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

现在,我认为这个问题的答案,说这是不可能的,是不完全正确的。看起来Scapy会让你发送10个字节的TCP块(我从here得到了块()函数)。我在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() 

服务器:

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 
相关问题