Python套接字发送速度比接收器快

Python套接字发送速度比接收器快,python,python-2.7,sockets,Python,Python 2.7,Sockets,因此,我有一个服务器使用socket.send()方法向客户机发送响应。在本地主机上测试代码时,当服务器连续两次使用socket.send()时,客户端用来接收服务器响应的socket.recv()方法会在一次中获得两条不同的消息。 例如: 服务器: 客户: from socket import * serverName = 'localhost' serverPort = 13005 clientSocket = socket(AF_INET, SOCK_STREAM) clientSock

因此,我有一个服务器使用socket.send()方法向客户机发送响应。在本地主机上测试代码时,当服务器连续两次使用socket.send()时,客户端用来接收服务器响应的socket.recv()方法会在一次中获得两条不同的消息。 例如: 服务器:

客户:

from socket import *

serverName = 'localhost'
serverPort = 13005
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
print clientSocket.recv(1024)
print clientSocket.recv(1024)
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 13005

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send('Message one\r\n')
s.send('Message two\r\n')
s.close()
随机运行客户端的结果是

Message oneMessage two

除非我在两个send()之间设置一个sleep(0.1)。有没有办法避免使用睡眠?我需要在recv()方法中输入接收的确切字节数吗?

TCP是一种面向流的协议,不逐个发送消息。拆分邮件的一种简单方法,您可以在邮件末尾设置拆分字符串,如
\r\n

例如:

客户:

from socket import *

serverName = 'localhost'
serverPort = 13005
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
print clientSocket.recv(1024)
print clientSocket.recv(1024)
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 13005

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send('Message one\r\n')
s.send('Message two\r\n')
s.close()
服务器:

#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 13005
BUFFER_SIZE = 20  # Normally 1024, but we want test

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
data = ''
while 1:
    data += conn.recv(BUFFER_SIZE)
    if not data: break
    if not data.endswith('\r\n'):
        continue
    lines = data.split('\r\n')
    for line in lines:
        print line
    data = ''
conn.close()

如果您的消息复杂且长,您可以看到:

TCP是一种面向流的协议,不逐个发送消息。拆分邮件的一种简单方法,您可以在邮件末尾设置拆分字符串,如
\r\n

例如:

客户:

from socket import *

serverName = 'localhost'
serverPort = 13005
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
print clientSocket.recv(1024)
print clientSocket.recv(1024)
#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 13005

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send('Message one\r\n')
s.send('Message two\r\n')
s.close()
服务器:

#!/usr/bin/env python

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 13005
BUFFER_SIZE = 20  # Normally 1024, but we want test

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
data = ''
while 1:
    data += conn.recv(BUFFER_SIZE)
    if not data: break
    if not data.endswith('\r\n'):
        continue
    lines = data.split('\r\n')
    for line in lines:
        print line
    data = ''
conn.close()

如果消息复杂且较长,您可以看到:

No,您需要创建一个协议来在原始字节流上对消息进行分隔(或重新使用现有协议)。SOCK_流套接字正如它所说的,是一个流。发送可以分组甚至拆分(一次发送产生多个recv)。这个天真的例子让你明白了这个想法:你可以在每条消息前加上字节大小,这样接收者就知道需要多少字节。顺便说一句,睡眠并不能解决你的问题。即使使用
sleep(15)
,如果出现网络延迟或数据包丢失并重新传输,您将在一个
recv
中获得所有数据。不,您需要创建一个协议来在原始字节流上限定消息(或重新使用现有协议)。SOCK_流套接字正如它所说的,是一个流。发送可以分组甚至拆分(一次发送产生多个recv)。这个天真的例子让你明白了这个想法:你可以在每条消息前加上字节大小,这样接收者就知道需要多少字节。顺便说一句,睡眠并不能解决你的问题。即使使用
sleep(15)
,如果出现网络延迟或数据包丢失并重新传输,您将在一个
recv
中获得所有数据。