1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr = TRUE;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(BOOL));
2.如果要已经处于连接状态的socket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s, SOL_SOCKET, SO_DONTLINGER,(const char*)&bDontLinger, sizeof(BOOL));
3.在send(), recv()过程中有时由于网络状况等原因,发收不能预期进行,而设置收发时限:
int nNetTimeout = 1000; //1秒
//发送时限
setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&nNetTimeout,sizeof(int));
//接受时限
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));
4.在send()的时候,返回的是实际发送出去的字节(同步)或发送到socket缓冲区的字节(异步);
系统默认的状态发送和接受一次为8688字节(约为8.5k);在实际的过程中发送数据和接受数据量比较大,可以设置socket缓冲区,而避免了send(),recv()不断的循环收发:
//接收缓冲区
int nRecvBuf = 32*1024; //设置为32k
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char *)&nRecvBuf,sizeof(int));
//发送缓冲区
int nSendBuf = 32*1024; //设置为32k
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (const char *)&nSendBuf,sizeof(int));
5. 如果在发送数据时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响程序的性能:
int nZero = 0;
setsockopt(socket, SOL_SOCKET, SO_SNDBUF,(char *)&nZero,sizeof(nZero));
6.同上在recv()完成上述功能(默认情况是将socket缓冲区的内容拷贝到系统缓冲区):
int nZero = 0;
setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char*)&nZero,sizeof(int));
7. 一般在发送UDP数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast = TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST, (const char*)&bBroadcast, sizeof(BOOL));
8. 在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可以设置connect()延时,直到accept()被呼叫(本函数设置只有在非阻塞的过程中有显著的作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept = TRUE;
setsockopt(s, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (const char*)&bConditionalAccept, sizeof(BOOL));
9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们一般采取的措施是“从容关闭” shutdown(s,SD_BOTH), 但是数据是肯定丢失了,如何设置让程序满足具体应用的要求(即让没发完的数据发送出去后再关闭socket)?
struct linger
{
u_short l_onoff;
u_short l_linger;
};
linger m_sLinger;
m_sLinger.l_onoff = 1; //(在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
// 如果m_sLinger.l_onoff=0;则功能和2.)作用相同;
m_sLinger.l_linger=5;//(容许逗留的时间为5秒)
setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger));