服务器代码:
import socket
import base64
filename = open("received.xvid","ab")
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
data = conn.recv(16)
filesize = int(data)
iter = filesize//BUFFER_SIZE
i = 0
while (i < iter):
data = conn.recv(BUFFER_SIZE)
filename.write(data.decode('base64'))
if not data:
continue
i = i + 1
data = conn.recv((filesize - (iter*BUFFER_SIZE)))
filename.write(data.decode('base64'))
filename.close()
conn.close()
客户代码:
import socket
import time
import base64
TCP_IP = '127.0.0.1'
TCP_PORT = 5005
BUFFER_SIZE = 1024
filename = open("test.xvid","rb")
MESSAGE = base64.b64encode(filename.read())
filesize = '%16s'%len(MESSAGE)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(filesize)
time.sleep(1)
s.send(MESSAGE)
s.close()
当我运行客户端代码时,我得到&#34; socket.error:[Errno 10061]无法建立连接,因为目标计算机主动拒绝它&#34;。我不明白为什么。我应该用什么代替TCP_IP和TCP_PORT来使代码工作?
这是我输入命令netstat -tnl时得到的。
显示协议统计信息和当前TCP / IP网络连接。
NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-x] [-t] [间隔]
-a显示所有连接和侦听端口。 -b显示创建每个连接所涉及的可执行文件 听口。在某些情况下,众所周知的可执行文件主机 多个独立的组件,在这些情况下 创建连接所涉及的组件序列 或显示监听端口。在这种情况下可执行文件 name位于底部的[]中,顶部是它调用的组件, 等等,直到达到TCP / IP。请注意,此选项 可能很费时,除非你有足够的,否则会失败 权限。 -e显示以太网统计信息。这可以与-s结合使用 选项。 -f显示外部的完全限定域名(FQDN) 地址。 -n以数字形式显示地址和端口号。 -o显示与每个连接关联的拥有进程ID。 -p proto显示proto指定的协议的连接;原 可以是以下任何一种:TCP,UDP,TCPv6或UDPv6。如果与-s一起使用 显示每个协议统计信息的选项,proto可以是以下任意一个: IP,IPv6,ICMP,ICMPv6,TCP,TCPv6,UDP或UDPv6。 -r显示路由表。 -s显示每个协议的统计信息。默认情况下,统计信息是 显示IP,IPv6,ICMP,ICMPv6,TCP,TCPv6,UDP和UDPv6; -p选项可用于指定默认的子集。 -t显示当前连接卸载状态。 -x显示NetworkDirect连接,侦听器和共享 端点。 -y显示所有连接的TCP连接模板。 不能与其他选项结合使用。 interval重新显示所选统计信息,暂停间隔秒 每个显示器之间。按CTRL + C以停止重新显示 统计。如果省略,netstat将打印当前 配置信息一次。
答案 0 :(得分:2)
当您等待在侦听套接字上accept
时,您将被置于待办事项中。此积压是有限且非常短 - 值为1,2或3并不罕见 - 因此操作系统可能无法将您的accept
消耗请求排入队列。
积压是listen
功能的参数 - 所有语言和平台在这方面都具有基本相同的API。如果您控制服务器,此参数通常是可配置的,并且可能从某些设置文件或注册表中读取。研究如何配置服务器。
无论是否可以增加服务器待办事项,您的客户端代码中都需要 重试 逻辑才能解决此问题如果服务器可能在那个时候在该端口上接收了很多其他请求,那么积压很长。
如果映射的端口耗尽,NAT路由器很少会出现此错误。我认为我们可以放弃这种可能性,因为路由器在耗尽之前有 64K 同时连接到相同的目标地址/端口。
另请查看此处了解更多原因:
答案 1 :(得分:0)
当我在同一台机器上运行服务器和客户端时,一切都很好。当我在不同的机器上运行时,就会出现问题。
好的,我知道你的问题是什么。
TCP_IP = '127.0.0.1'
您已将此IP地址硬编码到服务器和客户端。这是一个特殊的IP地址,意味着这台机器,只有这台机器。在bind()
中使用它时,服务器将从同一台计算机上侦听仅的连接。在connect()
中使用它时,客户端会尝试连接到在同一台计算机上运行的服务器。
要侦听来自任何计算机的连接(可能是您对服务器的意图),请使用特殊IP地址bind
来呼叫0.0.0.0
。 (用于生产的完整服务器需要做一些比这更复杂的事情,但这对于像这样的测试程序来说已经足够了。)
要让客户端连接到另一台计算机上运行的服务器,需要将另一台计算机的DNS名称作为命令行参数,并通过getaddrinfo
运行以获取要连接的IP地址
您应该购买并阅读UNIX Network Programming, Volume 1, 3rd Edition和Advanced Programming in the UNIX Environment。它们很贵,但它们是值得的。如果您要编写完整的网络服务器或客户端,他们将充实上述建议并教您许多其他需要了解的事项。 (确保获得第三版 UNIX网络编程;早期版本包含一堆您不需要了解的过时垃圾。 UNIX网络编程的第二卷< / em>也很有价值但不适用于你当前的情况。高级编程... 也没那么紧密相关,特别是如果你在Windows上,因为我怀疑你是来自于错误信息。)