【发布时间】:2015-10-14 01:07:57
【问题描述】:
我在“localhost”上使用客户端/服务器连接,服务器用 Python 编写,客户端用 Perl 编写。
每次(Perl)客户端向服务器传输数据时,我当前都会使用以下行创建一个新套接字:
my $socket = new IO::Socket::INET ( PeerHost => inet_ntoa($self->{server}),
PeerPort => $self->{port}, Proto => 'tcp' );
然后我使用 send 方法发送数据并使用选项 1(完成写入)调用 shutdown。然后我收到带有 recv 方法的响应,并使用选项 2 调用关闭(完成阅读)。然后我在套接字上调用 close 。在 Perl 中是这样写的:
$socket->send($record);
shutdown($socket, 1);
my $response = "";
$socket->recv($response, BUF_SIZE);
shutdown($socket, 0);
$socket->close();
由于我的套接字存储在一个局部变量中,我希望它在我离开我的发送函数后得到垃圾收集。但是,每次我创建一个新套接字时,内存占用都会增加几千字节。
然后,经过数千次调用,新套接字的创建失败。如果我然后等待几秒钟再试一次,它通常会创建好,尽管在此期间进程的内存占用没有改变。
有人能告诉我这种奇怪行为的原因,甚至是避免它的解决方案吗?
只是为了完成 - 这是在 Python 中创建服务器套接字的方式:
comm_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
comm_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
comm_socket.bind((TCP_IP, TCP_PORT))
comm_socket.listen(1)
【问题讨论】:
-
您是否在测试您的关闭/关机等是否确实有效,当它出现异常时,“netstat -a”会告诉您什么?因为这听起来像是打开套接字过多的问题。
-
你告诉我们。检查每个套接字函数调用的返回值和
$!。 -
我同意 Sobrique 的观点;我不知道你在做什么是否允许这样做,但如果可能的话,我建议重构你的实现以尽可能重用套接字
-
感谢您这么快回答!套接字上的任何函数调用都不会标记错误。仅当创建新套接字失败时,我才得到“每个套接字地址(协议/网络地址/端口)通常只允许使用一次。”这个问题经常出现几秒;然后一切都继续正常工作几分钟,直到问题再次出现(同样只有几秒钟)。当问题出现时,我等待 1..3 秒,然后重试创建套接字,直到最终成功。
-
大卫:“你为什么这样做?”是什么意思。您的意思是一直重新创建套接字吗?如果是这样:我不知道,如何重新使用它。你能告诉我吗?