#include <sys/types.h >
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
複製代碼
(1)若是在已經處於 ESTABLISHED狀態下的socket(通常由端口號和標誌符區分)調用close(socket)(通常不會當即關閉而經歷TIME_WAIT的過程)後想繼續重用該socket:bash
int reuse=1;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)& reuse,sizeof(int));
複製代碼
注意:必須在調用bind函數以前設置SO_REUSEADDR選項。服務器
(2)若是要已經處於鏈接狀態的soket在調用close(socket)後強制關閉,不經歷TIME_WAIT的過程:網絡
int reuse=0;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)& reuse,sizeof(int));
複製代碼
(3)在send(),recv()過程當中有時因爲網絡情況等緣由,發收不能預期進行,而設置收發時限:異步
int nNetTimeout=1000; // 1秒
// 發送時限
setsockopt(socket,SOL_S0CKET, SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
// 接收時限
setsockopt(socket,SOL_S0CKET, SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
複製代碼
(4)在send()的時候,返回的是實際發送出去的字節(同步)或發送到socket緩衝區的字節(異步),系統默認的狀態發送和接收一次爲8688字節(約爲8.5K);在實際的過程當中發送數據和接收數據量比較大,能夠設置socket緩衝區,而避免了send(),recv()不斷的循環收發:socket
// 接收緩衝區
int nRecvBuf=32*1024; // 設置爲32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
// 發送緩衝區
int nSendBuf=32*1024; // 設置爲32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
複製代碼
注意:並非說你設置的多大,系統就會設置多大,系統通常會將咱們設置的緩衝區大小加倍,而且不得小於tcp的接收緩衝區和發送緩衝區設置的默認最小值。 注意:TCP有發送緩衝區和接收緩衝區,可是UDP由於是不可靠的,它沒有確認重傳機制,不保存應用程序數據的副本,因此是沒有發送緩衝區的,可是UDP有接收緩衝區。tcp
(5)若是在發送數據時,但願不經歷由系統緩衝區到socket緩衝區的拷貝而影響程序的性能:函數
int nZero=0;
setsockopt(socket,SOL_SOCKET,SO_SNDBUF,(char *)&nZero,sizeof(int));
複製代碼
(6)同上在recv()完成上述功能(默認狀況是將socket緩衝區的內容拷貝到系統緩衝區):性能
int nZero=0;
setsockopt(socket,SOL_SOCKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
複製代碼
(7)通常在發送UDP數據報的時候,但願該socket發送的數據具備廣播特性:ui
int bBroadcast = 1;
setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char*)&bBroadcast, sizeof(int));
複製代碼
(8)設置存活檢測spa
int opt = 1;
if (setsockopt (m_nSock, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(int)) == -1)
{
return 0;
}
複製代碼
(9)延遲接收 實際上就是當接收到第一個數據以後,纔會建立鏈接。對於像http這類非交互式的服務器,這個頗有意義,能夠防護空鏈接攻擊。
int val = 5;
setsockopt(fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val));
複製代碼
打開這個功能後,內核在val時間之類尚未收到數據,不會繼續喚醒進程,而是直接丟棄鏈接。
從三次握手上講,就是設置這個狀態以後,就算完成了三次握手,服務器socket狀態也不是ESTABLISHED,而依然是 SYN_RCVD,不會去接收數據。