35

我正在尝试在 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 中编程。关于如何解决这个问题的任何想法?

4

7 回答 7

42

在 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

祝你好运。

于 2016-06-13T21:11:03.743 回答
31

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

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
于 2012-09-11T04:07:35.983 回答
5

在@JohnKugelman 发布的文章中指出,即使启用后,SO_REUSEADDR您也无法使用套接字连接到与以前相同的远程端:

SO_REUSADDR 允许您使用卡在 TIME_WAIT 中的端口,但您仍然不能使用该端口建立与它连接的最后一个位置的连接。

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

出于测试目的,如果您只是serverPort以循环方式更改您的方式也可以,您怎么看?

于 2012-09-11T08:45:48.240 回答
2

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

于 2019-06-24T09:57:50.063 回答
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()

帮助?

于 2012-09-11T04:15:11.967 回答
0

我将端口号更改为不同的端口号,它可以工作。

if __name__ == '__main__':
    socketio.run(app, debug = True, use_reloader = False, port=1111)
于 2018-10-17T15:59:14.513 回答
0

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

外壳->重新启动外壳。

如果您已经在没有停止服务器的情况下关闭了 shell,请转到任务管理器并在后台处理器中结束任务python 进程。这将停止服务器的最后一刻。

于 2017-07-24T08:49:35.350 回答