import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = ("0.0.0.0", 9000)
server.bind(addr)
server.listen(5)
while 1:
print("waiting for connection")
client, address = server.accept()
print("connection from {}:{}".format(address[0], address[1]))
while 1:
data = client.recv(1024)
if data == b"":
break
print(data)
client.close()
print("close connection from {}:{}".format(address[0], address[1]))
import socket
addr = ("localhost", 9000)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(addr)
client.close()
client.connect(addr)
1
opengps 2020-06-12 16:42:35 +08:00
我不懂 py,但我理解 socket 连接不能这么复用(直接断直接重开)。
在 c#下得先=null 然后重新 new 才能使用新的对象建立连接 |
2
limboMu 2020-06-12 16:55:59 +08:00
TCP 主动关闭一方,是要等待 2msl 才能复用端口的,重新连接多半是要换一个端口,so 原来的 socket 实例是不能使用的
|
3
ysc3839 2020-06-12 16:58:49 +08:00 via Android
要重新调用 socket.socket 创建个新的吧?
|
4
18870715400 OP @limboMu
等 2msl 是什么意思, 等 2 毫秒么 client.connect(addr)之前再重新赋值下 client client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 这样就不会报错 |
5
18870715400 OP @ysc3839 的确是需要建立一个新的
|
6
est 2020-06-12 17:08:04 +08:00
client.connect(addr)
这个不能重复写。得再弄一个 client2 |
7
limboMu 2020-06-12 17:11:38 +08:00
@18870715400 2msl 是个虚数,很长可能半分钟也可能一分钟,这个取决于操作系统的网络协议栈的实现,建议了解一下 TCP 的状态机
|
8
lackywind 2020-06-12 18:07:23 +08:00
最后一个 client.connect(addr) 应该是把套接字的句柄给关闭了,需要再重新创建下
import socket addr = ("localhost", 9000) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(addr) client.close() client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(addr) |
9
sujin190 2020-06-12 18:22:33 +08:00
socket 创建的也是文件句柄,你都关闭了,那么这个文件句柄在内核里就直接被释放了啊,你在操作他当然不行了,就好比你一个文件打开然后关闭再读写当然不行了
第二个也是上面说的,tcp 为了过滤异常包所以关闭后会继续保持占用一段时间端口,立刻重用这个端口也是不行的 |
10
HanMeiM 2020-06-12 19:57:12 +08:00
2msl 是指两倍的报文最长生存时间,保证被关闭的一方确定收到 ack 和旧数据的清除
|
11
youngce 2020-06-12 20:51:13 +08:00
刚好之前做过类似 tcp 断线(实际上可能是服务端暂时不可用)重连的机制,一般是 client.close()主动 sleep 一段时间,然后再重新发起 client.connect(addr),这样就避免了你这里的报错
|
12
yannxia 2020-06-12 21:16:16 +08:00
Socket 被 close 就约等于 FD 被 lose 约等于 此次的 TCP 链路结束了,再 Connect 需要一个 新的 FD,也就是创建一个新的 Socket
|
13
18870715400 OP @sujin190 看到你的例子突然懂了, 谢谢
|