今天做project,遇到一个很有意思的问题。
首先客户端向服务端发出一个请求包,包里包含mode, packet num,packet size,rate 等参数。服务端根据这些参数,向客户端建立TCP或者UDP 并发包。
一开始,由于想要直接使用UDP recvfrom(receiverSocket, recvbuf, recvbuflen, 0, (sockaddr *)&remoteAddr, &nAddrLen) 函数中的remoteAddr拿来做客户端的地址,然后向这个地址发包。但是发现,客户端那边无法正常接收。debug之后发现是,客户端里我接收的socket和之前发送请求包的socket无法共用一个地址(确切的说是port number)。可是我明明已经在发送完请求包后就关闭了负责发送的socket。网上查了之后,知道了即使关闭了socket,OS会默认保留这个port一段时间。蛋疼~~~
于是,搜索了一些方法,网上有大神提出,使用SO_REUSEADDR 属性
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flag, len)
具体代码见:http://blog.youkuaiyun.com/liusujian02/article/details/1944520
但是很不幸,我使用了这种方法后,bind的过程,程序提示10013错误,就是没有权限进行bind。具体原因不清楚(我猜还是这个方法没起作用,或者是OS设置了其他限制)。无奈,最后索性放弃了共用一个port的想法。
(如果有读者也遇到类似问题,但是成功解决了麻烦告诉我一下!多谢~)
···
最后,我选择使用一个更鸡贼的办法——在recvfrom()中得到的remoteAddr里,我将remoteAddr.sin_port++,在客户端那边设置receiving socket绑定的port number为sending socket的port经过htons()函数处理后加1的数字。问题就这么愉快的解决了,晚安!~~~(不过我还是挺想知道怎么能快速释放一个socket绑定的port)