Python服务器“通常只允许使用每个套接字地址”

时间:2012-09-11 03:56:38

标签: python sockets connection webserver

我正在尝试在python中创建一个非常基本的服务器,用于侦听端口,在客户端尝试连接时创建TCP连接,接收数据,发回一些内容,然后再次侦听(并无限期地重复该过程) 。这就是我到目前为止所做的:

from socket import *

serverName = "localhost"
serverPort = 4444
BUFFER_SIZE = 1024

s = socket(AF_INET, SOCK_STREAM)
s.bind((serverName, serverPort))
s.listen(1)

print "Server is ready to receive data..."

while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()

有时这看起来效果非常好(如果我将浏览器指向“localhost:4444”,服务器会打印出HTTP GET请求,而网页会打印文本“hello world”)。但是,当我在最后几分钟关闭它后尝试启动服务器时,偶尔会收到以下错误消息:

Traceback (most recent call last):
  File "path\server.py", line 8, in <module>
    s.bind((serverName, serverPort))
  File "C:\Python27\lib\socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

我正在使用Windows 7在python中编程。有关如何解决此问题的任何想法?

7 个答案:

答案 0 :(得分:18)

在调用bind()之前启用SO_REUSEADDR套接字选项。这允许地址/端口立即重用,而不是在TIME_WAIT状态下停留几分钟,等待迟到的数据包到达。

s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

答案 1 :(得分:13)

在Windows上,您可以尝试以下步骤:

1。检查哪个进程使用该端口。

# 4444 is your port number
netstat -ano|findstr 4444
你会得到这样的东西:

# 19088 is the PID of the process
TCP    0.0.0.0:4444           *:*                                    19088

2。杀死这个过程

使用:

tskill 19088

或者:

taskkill /F /PID 19088
祝你好运。

答案 2 :(得分:3)

在@JohnKugelman发布的the article中,声明即使启用SO_REUSEADDR后,也无法使用套接字连接到同一个远程端:

  

SO_REUSADDR允许您使用卡在TIME_WAIT中的端口,但是   您仍然无法使用该端口建立与最后一个的连接   将它连接到。

我看到你只是在测试/玩游戏。但是,要避免此错误,您确实需要确保正确终止连接。您还可能会弄乱操作系统的tcp时序:http://www.linuxquestions.org/questions/linux-networking-3/decrease-time_wait-558399/

出于测试目的,如果你只是以循环方式改变你的serverPort,你会怎么样?

答案 3 :(得分:0)

关闭套接字非常重要(在Windows上)。否则,在关闭Python之后你必须等待它超时。

将:

try:
    while 1:
        newConnection, client = s.accept()
        msg = newConnection.recv(BUFFER_SIZE)

        print msg

        newConnection.send("hello world")
        newConnection.close()
finally:
    s.close()

帮助?

答案 4 :(得分:0)

如果您尝试重新运行服务器而不停止服务器的最后一刻,它将无法运行。如果你想停止当前的瞬间,请转到

shell - &gt;重新启动shell。

如果你已经关闭了shell 停止服务器转到后台处理器中的任务管理器结束任务 python进程。这将停止服务器的最后一刻。

答案 5 :(得分:0)

我将端口号更改为另一个,并且可以正常工作。

if __name__ == '__main__':
    socketio.run(app, debug = True, use_reloader = False, port=1111)

答案 6 :(得分:0)

可能是因为您尚未终止服务器代码,并试图在另一个cmd上再次运行它。无法将服务器托管在相同的端口号上,请尝试终止以前的托管服务器。