我使用Python Socket在Ubuntu服务器上实现两个本地进程之间的交互。发生了一些奇怪的事情。当我在Mac(i7)上本地运行两个进程时,它们在1秒内快速运行。但是,当我在Ubuntu服务器上运行它们时,花费超过30秒。
我认为TCP在Send()和Recv()之间被阻塞。当我只是让服务器发送和客户端接收消息时。然后进程也可以在1秒内运行。所以我想知道发生了什么,是否有可能修复它。非常感谢!
这里是代码
伺服器:
if __name__=='__main__':
server1 = ServerSocket("127.0.0.1", 4321)
server1._conn_client()
print("xxx");
start_time = time.time()
for i in range(10000):
server1.Recv()
server1.Send("hello") ## delete this row to disable the server to send messages
print(i)
end_time = time.time()
print("Server time:", end_time - start_time)
server1.Send("hello")
msg = server1.Recv()
print("hi:", msg)
server1.close()
字符串
委托方:
if __name__ == '__main__':
client = ClientSocket("127.0.0.1", 4321)
client.Connect()
print("xxx");
start = time.time()
for i in range(10000):
client.Send("hello from client1")
client.Recv() ## delete this to disable the cleint to receive messages
end = time.time()
print("Client time:", end - start)
msg =client.Recv()
print(msg)
client.Send("hello from client1")
client.close()
型
从其他函数定义的套接字函数:
class ServerSocket(object):
def __init__(self, ip="127.0.0.1", port=7778):
self.ip = ip
self.port = port
self._buffer_size = 80000
self._init_socket()
self._socket.settimeout(3000)
def _init_socket(self):
self._socket = socket.socket()
ip_port = (self.ip, self.port)
self._socket.bind(ip_port)
def _conn_client(self):
self._socket.listen(100)
self._client_socket, addr = self._socket.accept()
self._client_socket.settimeout(3000)
def Recv(self):
msg_len_pack = self._client_socket.recv(4)
# print(struct.unpack('i', msg_len_pack))
msg_len = struct.unpack('i', msg_len_pack)[0]
# print("msg_len:", msg_len, "buffer:", self._buffer_size)
if msg_len < self._buffer_size:
msg_pack = self._client_socket.recv(msg_len)
msg = json.loads(msg_pack.decode('utf-8'))
return msg
def Send(self,data):
msg_pack = json.dumps(data).encode('utf-8')
msg_len_pack = struct.pack('i', len(msg_pack))
self._client_socket.send(msg_len_pack)
self._client_socket.send(msg_pack)
def close(self):
self._client_socket.close()
class ClientSocket(object):
def __init__(self, ip="127.0.0.1", port=7778):
self.ip = ip
self.port = port
self._buffer_size = 80000
def Connect(self):
self._socket = socket.socket()
self._socket.connect((self.ip,self.port))
def Send(self, data):
msg_pack = json.dumps(data).encode('utf-8')
msg_len_pack = struct.pack('i', len(msg_pack))
self._socket.send(msg_len_pack)
self._socket.send(msg_pack)
def Recv(self):
msg_len_pack = self._socket.recv(4)
msg_len = struct.unpack('i', msg_len_pack)[0]
if msg_len < self._buffer_size:
msg_pack = self._socket.recv(msg_len)
msg = json.loads(msg_pack.decode('utf-8'))
return msg
def close(self):
self._socket.close()
型
1条答案
按热度按时间qvtsj1bj1#
巨大的延迟来自于你的优化:D啊哈,开玩笑的,我理解你使用结构体发送超过4字节的msg大小,然后稍后发送完整的msg,而接收方等待确切的msg长度,等等.但这是一个“错误”的优化在你的情况下。只要坚持默认的缓冲区大小,如1024或4096或任何2的幂,不太大也不太小。
然后处理它:你仍然可以发送JSON数据来给予关于未来的信息,关于下一个“大消息”,这将是4 GB或什么,它将通过多个套接字包发送,仅此而已
此外,让我们避免在相同的情况下重复代码,在您的情况下,可以使用单个类:
字符串
然后你只需要为客户端示例化一种不同的方式:
型
对于服务器:
型
在Ubuntu上,超过10000的循环总共不到0.3秒,包括打印,我猜这需要大部分时间。