Monthly Archives: March 2010

解决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类型。

Posted in Uncategorized | Tagged , , , , | Leave a comment

2012真的是世界末日?

今天三国杀群里收到一个链接:
http://www.tianya.cn/publicforum/content/funinfo/1/1854401.shtml

看了之后发现,这个是目前所有关于外星人的消息中最靠谱的一个。如果NASA的照片是真的,那说明人类将会面临一次巨大的事件。而且发生的日期近在眼前。看完了帖子,立刻搜索了相关内容。发现这个东西现在异常的火。

我要承认,有生以来第一次感受到了对未知的恐惧。其实是真是假不重要,因为即使是真的,以人类目前的科技水平,几乎束手无策。这一伙外星人与人类的关系,就像人类和蚂蚁的关系一样。因此自然而然的引出几种假设。其中最悲观的是,世界末日即将到来。那么,在世界末日来临前,我想要做些什么呢?

。。。。。。。。(个人隐私,省略若干文字)

恩,就这些。在思考这个严肃问题的时候,氛围是必不可少的。各位也好好想想吧!

Posted in Uncategorized | Tagged , , , | Leave a comment