套接字有很多的选项需要设置,同时也需要获取套接字的一些状态信息,一般用getsocketopt和setsocketopt执行这些操作
头文件
int getsocketopt(int sockfd, int level, int optname, void *opval, socketlen_t *oplen);
getsocket函数把获取的信息存到opval和oplen中
socket:文件描述符
level:协议层次
SOL_SOCKET 套接字层次
IPPROTO_IP ip层次
IPPROTO_TCP TCP层次
optname:选项的名称
返回值:
成功:0
失败:-1
头文件
int setsocketopt(int sockfd, int level, int optname, void *opval, socketlen_t oplen);
setsockopt把要设置的信息通过opval和oplen进行传送
SO_KEEPALIVE的开启代码:
int KeepAlive = 1;
setsocketopt(fd, SOL_SOCKET, SO_KEEPALIVE,(void *)&KeepAlive,sizeof(KeepAlive));
SO_KEEPALIVE的关闭代码:
int KeepAlive = 0;
setsocketopt(fd, SOL_SOCKET, SO_KEEPALIVE,(void *)&KeepAlive,sizeof(KeepAlive));
SO_KEEPALIVE的状态获取代码:
int KeepAlive, len;
getsocketopt(fd, SOL_SOCKET, SO_KEEPALIVE,(void *)&KeepAlive,&len);
给一个套接字开启保活选项后,如果2小时内该套接字的任意一个方向都没有数据交换,则TCP就会给对端发送一个保持存活探测分节,这时一个对端必须响应的分节,它会导致以下三种情况之一:
TCP_NODELAY的开启代码:
int KeepNoDelay = 1;
setsocketopt(fd, IPPROTO_TCP, TCP_NODELAY,(void *)&KeepNoDelay ,sizeof(KeepNoDelay));
TCP_NODELAY的关闭代码
int KeepNoDelay = 0;
setsocketopt(fd, IPPROTO_TCP, TCP_NODELAY,(void *)&KeepNoDelay ,sizeof(KeepNoDelay));
SO_KEEPALIVE的状态获取代码:
int KeepNoDelay, len;
getsocketopt(fd, IPPROTO_TCP, TCP_NODELAY,(void *)&KeepNoDelay ,&len);
Nagle算法:如果在某个连接上有待确认的数据,那么该连接上的小分组(小于MSS的分组)就不会被发送。该算法可以减少小分组的数量,从而尽可能发送大分组。
ACK延滞算法:TCP在接收到数据后不立即发送ACK,而是的等待一小段时间(50-200ms), 再发送ACK。该算法期待这一小段时间可以等到一段需要发送的数据,从而提高效率。
这两个算法一般联合使用。
开启TCP_NODELAY将关闭Nagle算法,反之开启。
设置接收缓冲区的大小
int setbuf=80000;
socklen_t len1=sizeof(setbuf);
setsockopt(listenfd,SOL_SOCKET,SO_RCVBUF,(void *)&setbuf,len1);
获取接收缓冲区的大小
getsockopt(listenfd,SOL_SOCKET,SO_RCVBUF,(void *)&buf_len,&len);
设置发送缓冲区的大小
int setbuf=80000;
socklen_t len1=sizeof(setbuf);
setsockopt(listenfd,SOL_SOCKET,SO_SNDBUF,(void *)&setbuf,len1);
获取发送缓冲区的大小
getsockopt(listenfd,SOL_SOCKET,SO_SNDBUF,(void *)&buf_len,&len);
TCP的套接字接收缓冲区不可能溢出,因为不允许对端发出超过本端所通告的接收缓冲区大小的数据。如果对端无视接收缓冲区大小而发出了超过接收缓冲区大小的数据,本段TCP将丢弃这些数据。
UDP没有流量控制,当接收到的数据超过接收缓冲区的大小,这些数据将被丢弃。
对于TCP而言,接收缓冲区的大小需要在connect函数(客户端)或者accept函数(服务端)被调用前设置。
给已连接的套接字设定接收缓冲区的大小可能不会起作用。
发送缓冲区和接收缓冲区的大小应该至少是MSS值的四倍(一般都是偶数倍),典型的MSS值为512或1460
缓冲区的大小设定为带宽延迟积(带宽*RTT)时,效率最高