必知的socket option-高级网络编程
Posted 安全研发币
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了必知的socket option-高级网络编程相关的知识,希望对你有一定的参考价值。
网络程序只是调用bind/listen/accept/recv/send就可以了吗?下面一些常用的socket的选项可以帮你避免一些麻烦或实现一些特殊需求。分析了几个开源的项目,包括nginx,Bitcoin等,都设置了大多下面的选项。
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses.
比如下面的例子,左侧窗口nc被异常退出后,socket就会处于TIME_WAIT状态,如果不设置这个选项,再监听在1111端口,就会失败。设置后就可以正常启动起来。
另一种情况是有一个监听在0.0.0.0:port的socket,如果设置了这个选项时,你仍然可以监听在具体的IP的同样的端口。当然反过来也可以成功。
比如下面的例子,左上窗口nc监听在0.0.0.0:1111,左下窗口nc仍然可以成功的监听在192.168.1.114:1111。右边客户端链接192.168.1.114:1111时,链接的是左下窗口的nc,等左下nc退出后,再连接192.168.1.114:1111时,才会连接到左上窗口的nc 。
下面是参考代码实现:
int reuseaddr = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(const void *) &reuseaddr, sizeof(int))
== -1)
{
return ERROR;
}
SO_REUSEPORT
比如下图,左边两个窗口的nc都绑定到了0.0.0.0:1111端口,右边的nc客户端能先连上一个,第二次连接了第二个,以此类推。nc能这样肯定是设置了这个选项的。
设置这个选项有更大的劫持流量的风险,需要谨慎使用。
参考代码如下:
int reuseport = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT,
(const void *) &reuseport, sizeof(int))
== -1)
{
// print some error message.
}
TCP_NODELAY
这个选项禁止了Nagle算法。Nagle算法为了减少网络上的小包数量,当数据小于一个长度限制,通常是MSS,等收到对方的ACK后再发发送积累的数据。如果你的程序期望尽快发送数据出去,减少延迟,比如telnet,就可以设置这个选项。
// Disable Nagle's algorithm
setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void *)&nOne,
sizeof(int));
非阻塞 FIONBIO
如果你不想你的socket的系统调用阻塞住,记得把socket设置成非阻塞。而且每个新accept的连接都要设置一下。
下面是参考代码实现。
#ifdef WIN32
u_long nOne = 1;
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) {
#else
int fFlags = fcntl(hSocket, F_GETFL, 0);
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == SOCKET_ERROR) {
#endif
return false;
欢迎 点赞,转发,打赏,谢谢!
以上是关于必知的socket option-高级网络编程的主要内容,如果未能解决你的问题,请参考以下文章