[转] 解决socket端口被占用的问题

这段时间遇到一个棘手的问题。现象如下:

VC6工程,程序a.exe使用TCP的Socket通讯。但当程序a.exe结束后,通讯中绑定的端口会始终处于监听状态,外部地址是0.0.0.0,所属的进程PID是已经结束了的a.exe原有的PID。已经确认,a.exe在结束前已经成功调用closesocket()关闭了socket,并调用了WSAClean()。但端口依旧被占用,处于LISTENING状态。

经过长时间研究发现,问题是由于创建子进程导致的。a.exe中会通过CreateProcess()创建android的adb.exe。如果此时是第一次调用adb.exe,则adb.exe会自动创建adb-server作为常驻进程,不会自己退出。而CreateProcess()中又设置了bInheritHandles和lpProcessAttributes.bInheritHandle两个参数为TRUE,这是为了能够得到子进程的stdin/out流。

但一旦设置了这两个参数,则CreateProcess()就会使创建的子进程继承了所有父进程的句柄,包括已经创建的Socket。因此,只有当adb-server的这个adb.exe进程结束,才会释放掉占用的Socket端口。

问题找到了,解决方法如下:

创建Socket时,首先创建一个SOCKET sOld。然后调用DuplicateHandle()复制出一个新的SOCKET s。DuplicateHandle()的参数中,bInheritHandle设置为FALSE,这就复制出了一个不能被子进程继承的SOCKET;同时指定参数dwOptions为DUPLICATE_CLOSE_SOURCE,使得sOld在被复制后自动关闭。接下来使用新的s来通讯。这样,Socket就不会被继承了。问题也就解决了。注意,使用DuplicateHandle()复制SOCKET时,需要强制转换SOCKET为HANDLE类型。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值