我试图编写一个代码,其中客户端通过默认端口号连接到服务器,然后服务器将另一个端口号发送到客户端。客户端现在连接到新的端口号。
客户:
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
有人可以向我解释这些错误的原因并提供这些错误的解决方案。
最佳答案
在你可以监听
一个TCP/IP套接字(一个基于连接的流套接字)之前你需要使用bind
来分配一个套接字(使用 socket.socket()
创建)。然后你需要做 listen
来为传入的连接做准备,最后你在准备好的套接字上做 accept
。
在调用 sock.bind(("127.0.0.1", port))
后,您似乎缺少 sock.listen(0)
。 Python documentation缺少详细信息,但它确实说明了 TCP/IP:
Note that a server must perform the sequence socket(), bind(), listen(), accept() (possibly repeating the accept() to service more than one client), while a client only needs the sequence socket(), connect(). Also note that the server does not sendall()/recv() on the socket it is listening on but on the new socket returned by accept().
Python 的套接字模块基于 Berkeley 套接字模型。您可以在此 link 中找到有关 Berkeley Sockets 的更多详细信息。 .特别是关于 bind
的内容:
bind() assigns a socket to an address. When a socket is created using socket(), it is only given a protocol family, but not assigned an address. This association with an address must be performed with the bind() system call before the socket can accept connections to other hosts.
还要考虑如果您的客户端在服务器开始监听连接(在本例中为端口 7777)之前收到一个端口号(并尝试连接)会发生什么情况。虽然不是你的问题的原因,但我想指出完整性的场景。您可能会考虑在端口 7777 套接字上调用 listen
之后才关闭端口 6667 套接字。在调用 listen
之后,您可以关闭第一个套接字。在客户端读取端口后,您可以等到第一个连接(端口 6667)被服务器关闭,然后连接到端口 7777。
关于python - 套接字错误 : [Errno 111] when trying to connect to a socket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26558303/