我试图编写一个代码,其中客户端在默认端口号上连接到服务器,然后服务器将另一个端口号发送到客户端。客户端现在连接到新的端口号。
客户端:
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
有人可以解释这些错误的原因并为这些错误提供解决方案。
答案 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.