socket.error:[Errno 111]尝试连接套接字时

时间:2014-10-25 00:58:42

标签: python sockets ports

我试图编写一个代码,其中客户端在默认端口号上连接到服务器,然后服务器将另一个端口号发送到客户端。客户端现在连接到新的端口号。

客户端:

import socket
import sys
import os
import signal
import time
s = socket.socket()
s.connect(("127.0.0.1", 6667))
line = s.recv(1024)
if line.strip():
    port = int(line)
    s.close()
    soc = socket.socket()
    soc.connect(("127.0.0.1", port))
    print soc.recv(1024)
    soc.close()
else:
    s.close()

服务器:

import socket
import sys
import os
import signal
import time
port = 7777
s = socket.socket()
s.bind(("127.0.0.1", 6667))
s.listen(0)
sc, address = s.accept()
print address
sc.send(str(port))
sc.close()
s.close()
sock = socket.socket()
sock.bind(("127.0.0.1", port))
soc, addr = sock.accept()
print addr
soc.send("Success")
soc.close()
sock.close()

当我执行此代码时,我在客户端和服务器端遇到以下错误。

服务器:

('127.0.0.1', 36282)
Traceback (most recent call last):
  File "server.py", line 17, in <module>
    soc, addr = sock.accept()
  File "/usr/lib/python2.7/socket.py", line 202, in accept
    sock, addr = self._sock.accept()
socket.error: [Errno 22] Invalid argument

客户端:

Traceback (most recent call last):
  File "client.py", line 13, in <module>
    soc.connect(("127.0.0.1", port))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused

有人可以解释这些错误的原因并为这些错误提供解决方案。

1 个答案:

答案 0 :(得分:1)

listen TCP / IP 套接字(基于连接的流式套接字)之前,您需要使用bind来分配套接字(使用{{1创建) })。然后,您需要socket.socket()为传入连接做好准备,最后在准备好的套接字上执行listen

致电accept后,您似乎缺少sock.listen(0)Python documentation的细节很简短,但它确实说明了TCP / IP:

  

请注意,服务器必须执行序列套接字() bind() listen() accept()(可能重复accept()来服务多个客户端),而客户端只需要序列socket(),connect()。另请注意,服务器不会在它正在侦听的套接字上发送all()/ recv(),而是在accept()返回的新套接字上发送。

Python将其套接字模块基于Berkeley套接字模型。您可以在link找到有关伯克利套接字的更多详细信息。特别是它说sock.bind(("127.0.0.1", port))

  

bind()为地址分配套接字。使用socket()创建套接字时,它仅被赋予协议族,但未分配地址。这个与地址的关联必须在bind()系统调用之前执行,然后套接字才能接受连接到其他主机。

还要考虑如果您的客户端在服务器开始侦听连接之前收到端口号(并尝试连接)会发生什么情况(在本例中为端口7777)。虽然不是问题的原因,但我想指出完整性的情景。在您在端口7777套接字上调用bind之后,您可能会考虑的事情是关闭端口6667套接字。在调用listen之后,您可以关闭第一个套接字。在读取端口后的客户端上,您可以等到服务器关闭第一个连接(端口6667),然后连接到端口7777.