大虾救命:TCP编程的客户端端口占用问题

pipy79 2003-03-13 11:21:57
加精

为什么在TCP连接后将SOCKET句柄用close()关闭后,
客户端的端口仍然占用,使用netstat察看状态为WAIT
用shutdown()关闭句柄也是一样的结果
并且要过一段时间以后才能清除
在windows和linux下我都遇到了这种情况,
其他操作系统还没有测试
请问祝位大虾应该如何解决这个问题呢?
...全文
471 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
pipy79 2003-06-16
  • 打赏
  • 举报
回复
谢谢大家的参与了
vencent 2003-05-06
  • 打赏
  • 举报
回复
2MSL
lurenfu 2003-04-21
  • 打赏
  • 举报
回复
可用setsockopt的SO_REUSEADDR选项解决
haidrau 2003-04-15
  • 打赏
  • 举报
回复
UNIX下的看R.stevens的书.
WinX的看RFC

TCP/IP timewaitstate will not remain in 2*MSL because of scavenging.
This happens even after applying the patch mentioned in:
Under sufficiently high TCP connection rates the Windows NT TCP/IP stack may reuse
TCP Control Blocks that are in the TIME-WAIT (also called the 2MSL state) table.
This can happen on a heavily loaded Web or FTP server when using graceful TCP closes.
Reuse of the Control Blocks may terminate a TCP connection in its TIME-WAIT state
prior to the 2MSL time period expiring.

There have been no reports of problems related to this symptom; however
the behavior is not RFC-compliant.

This behavior can occur because computers that run Microsoft Windows NT clients
and use excessive numbers of ports (more than 3,976 simultaneously) may run out of
ports before TCP/IP releases closed connections. The TCP/IP-state computer
dictates that when a connection is closed, the connection is not released until
two maximum segment lives (MSLs) have passed. This state is defined as the
Time-wait state. Since one MSL is defined as 120 seconds, it takes four minutes
for a closed connection to be released in TCP/IP.

NOTE: For more information on MSL and Time-wait,
please refer to Internet RFC 793.



xfxia 2003-04-04
  • 打赏
  • 举报
回复
这个问题我碰到过,也已经解决了。不过解决方法比较变态,本人觉得不好,也搞不懂为什么。应该是操作系统的问题。

解决方法就是在服务端处理完所有请求之后,在closesocket之前,向客户端发送1个或者多个字节的数据就可以了。
zb_china 2003-03-30
  • 打赏
  • 举报
回复
客户端这不是个问题,系统的处理就是这样的,客户端用系统自动分配的端口,延迟关闭不会造成任何问题。
Qinzijian 2003-03-30
  • 打赏
  • 举报
回复
客户端要关闭之前提交一个请求给服务器端关闭。由服务器端主动关闭连接可能就行了。
isforce 2003-03-29
  • 打赏
  • 举报
回复
能不能用JAVA写一个
??
功名半纸 2003-03-19
  • 打赏
  • 举报
回复
同意 zsh365(zsh365)

通常情况下只有-方--执行主动关闭操作的一方---进入TIME_WAIT状态,并为2个最大段生存时间(2MSL)保留在此状态;

设立TIME_WAIT状态有2个目的:
当主动关闭方发送最后的ACK消息丢失并导致另一方重新发送FIN消息时,TIME_WAIT维护连接状态;
为连接中的延迟或重串段通过确保旧套接字对在旧连接的段在网络上不会消失;

使用SO_LINGER套接字选项,和一linger结构,可以强制立即关闭连接.如立即关闭连接,即close或closesocket调用立即返回,由操作系统内核处理递交任何没有发送出去的数据。
如不是(linger结构中的l_onoff为非零值)就为操作系统内核停留的时间间隔,等待任何将要发送和确认的挂起数据,也就是说close 或closesocket直到所有数据被递交或时间间隔到时才返回。


如果使用 SO_REUSEADDR套接字选项有一个小的风险。在服务端绑定通配符地址INADDR_ANY,有可能被另一设置SO_REUSEADDR的服务器窃听前一个服务器的连接.
zsh365 2003-03-17
  • 打赏
  • 举报
回复
TIME_WAIT 应该说是tcp的防卫措施(防止后面重用端口号,导致数据与前面的连接分组混要), 这个东西R.stevens 的书说的很清楚了。 正常的状况下,你的client的端口每次都是临时制定的, 你没有必要为这个担心, 除非你想用bind指定客户端的端口号。
哪边调用close,就会在那一边出现TIME_WAIT的状态。 如果你是server端主动关闭, 才有必要使用shutdown。
dashi 2003-03-17
  • 打赏
  • 举报
回复
bnwxf 2003-03-17
  • 打赏
  • 举报
回复
如果两边都调用了close,TIME_WAIT状态用netstat应该看不到(时间太短)
看看你的代码,有没有在read时判断连接是否断开。
老问题了,unix网络编程 有很详细的解释和代码。
polehorse 2003-03-16
  • 打赏
  • 举报
回复
同意楼上的
VampireQQ 2003-03-15
  • 打赏
  • 举报
回复
这个问题一般在服务器端遇到,因为服务器的端口总是固定的,而在客户端,没有特殊需要,不帮定端口,让系统自己选择可用的剩余端口,你是不是在客户端的程序里面也使用了bind?不然的话,就不会遇到这个问题,客户端程序每次启动,就会使用不同的端口,而不会去使用上一次启动时用过的那个端口,因为那个端口还处在time_wait状态,不可使用,除非你setsockopt去修改so_reuse选项。
功名半纸 2003-03-14
  • 打赏
  • 举报
回复
为了把以前连接的报文段与当前连接的报文段区分开犁,TCP在关闭一个连接之后就进入TIMED_WAIT状态。他在这个状态中停留的时间达到最长报文段寿命的2倍时,就删去该连接的记录。如果在这个时限内有重复的报文段到达,TCP就会拒绝接收他。然而为了处理上一个确认丢失的情况,TCP对有效的报文段进行确认并重新设定定时器。定时器使得TCP能够辨别出新的连接和旧的连接,这就防止了本端以一个RST操作响应另一端重传的FIN请求!
功名半纸 2003-03-14
  • 打赏
  • 举报
回复
The SO_LINGER option controls the action taken when unsent data is queued on a socket and a closesocket is performed. See closesocket for a description of the way in which the SO_LINGER settings affect the semantics of closesocket. The application sets the desired behavior by creating a LINGER structure (pointed to by the optval parameter) with these members l_onoff and l_linger set appropriately.

要先调用 shutdown
hecrics 2003-03-14
  • 打赏
  • 举报
回复
一般不会有什么很大的影响吧?
但是2MSL是为了防止服务器重传最后一次数据,如果不设置这个的话,客户端接受到这个数据就不知道会怎么处理了,具体后果不清楚
功名半纸 2003-03-13
  • 打赏
  • 举报
回复
设置TIME_WAIT为0!!!!!!!!!

SO_LINGER 选项

linger.l_onoff = 1
linger.l_linger = 5
setsockopt(s, SOL_SOCKET, SO_LINGER, linger, sizeof(linger))

或者关闭TIME_WAIT
glhx 2003-03-13
  • 打赏
  • 举报
回复
你是否先shutdown,再close???
lichungen 2003-03-13
  • 打赏
  • 举报
回复
你把代码贴出来看看,我的程序好象没有这个问题(windows me)你的代码如下。
Socket.Close();
Socket.Create();
加载更多回复(3)

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧