1、bind的作用。
在tcp中, 表明要绑定到哪个端口和ip,bind函数中需要指定Ip和port。下面是tcp中server端和client端的bind的作用
在server端,是必须要进行bind的,一定需要指定server使用哪个端口。ip可以设置为0.0.0.0(Any),表示去监听电脑上的任意的网卡或者network adapter 。
在client端,可以bind,但是尽量不要bind。client端connect时,如果未bind,会自己默认绑定一个有效的ip和port。
在udp中, 哪方需要接收数据,哪方就需要bind,同样的,对于接收方可以设置ip 为0.0.0.0(Any),表示接收任意的网卡或adapter 的数据包。
不管是tcp还是udp,bind后,如果bind了ip为0.0.0.0,对于发送方,实际发送时会默认选择一个有效ip作为数据包的源。
需要注意,如果bind的ip和port在当前操作系统中的现有的tcp链接中存在,则会失败。
wireshark抓取本机数据包(包括回环地址),需要进行特殊设置:https://blog.csdn.net/readiay/article/details/53063932
2、m_clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //c# code
根据tcp 状态图:https://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html 可以了解到TIME_WAIT是正常关闭socket时,tcp链接会进入的一个状态,所有正常关闭socket会维持这个状态2MSL,一个MSL根据系统而定,默认可能是30ms、1min、2min。(注意,状态图描述的是tcp链接,而不是单指端口或者ip,或者两者的组合组合)
https://blog.csdn.net/yhcs1213/article/details/48293577 ,这个地址描述了如何取巧的让tcp链接不进入TIME_WAIT 状态, 但是这应该是不安全的,也不是主流,也不是推荐的。
tcp中的SOL_SOCKET 一个选项SO_REUSEADDR .描述的是是否允许端口在TIME_WAIT 状态时重用地址(ip+port)。如果不设置该值,则在bind的时候就会失败。
3、在一个电脑上进行服务端和客户端测试,设置了SO_REUSEADDR,但是connect的时候有时候会失败,失败后需要在一两分钟才能再次connect成功。找到原因是因为同样的tcp链接的描述在现有的链接中以存在,处于TIME_WAIT状态。虽然两端都进行了bind,并且两端都有设置SO_REUSEADDR。可能操作系统中一个tcp链接由两端的ip和端口组成的四元组来描述。如果查表时,发现同样顺序的四元组,就会返回fail。破解方式是,client端不进行bind。
4、socket 在close后必须要重新createsocket。serversocket 让阻塞中的accpet函数退出,需要调用close,close后也必需要 重新createsocket