setsockopt()用法(转载)
1.?? 如果在已經處于?? ESTABLISHED狀態下的socket(一般由端口號和標志符區分)調用??
? closesocket(一般不會立即關閉而經歷TIME_WAIT的過程)后想繼續重用該socket:??
? BOOL?? bReuseaddr=TRUE;??
? setsockopt(s,SOL_SOCKET?? ,SO_REUSEADDR,(const?? char*)&bReuseaddr,sizeof(BOOL));??
? 2.?? 如果要已經處于連接狀態的soket在調用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_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()不斷的循環收發:??
? //?? 接收緩沖區??
? 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));??
? 5.?? 如果在發送數據的時,希望不經歷由系統緩沖區到socket緩沖區的拷貝而影響??
? 程序的性能:??
? int?? nZero=0;??
? setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char?? *)&nZero,sizeof(nZero));??
? 6.同上在recv()完成上述功能(默認情況是將socket緩沖區的內容拷貝到系統緩沖區):??
? int?? nZero=0;??
? setsockopt(socket,SOL_S0CKET,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()延時,直到accpet()被呼叫(本函數設置只有在非阻塞的過程中有顯著的??
? 作用,在阻塞的函數調用中作用不大)??
? 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));??
? Note:1.在設置了逗留延時,用于一個非阻塞的socket是作用不大的,最好不用;??
??????????? 2.如果想要程序不經歷SO_LINGER需要設置SO_DONTLINGER,或者設置l_onoff=0;??
? 10.還一個用的比較少的是在SDI或者是Dialog的程序中,可以記錄socket的調試信息:??
? (前不久做過這個函數的測試,調式信息可以保存,包括socket建立時候的參數,采用的??
? 具體協議,以及出錯的代碼都可以記錄下來)??
? BOOL?? bDebug=TRUE;??
? 11.發送數據時候一般是系統緩沖區滿以后才發送,現在設置為只要系統??
? 緩沖區有數據就立刻發送:??????
? BOOL?? bNodelay=TRUE;??
? SetSockOpt(s,IPPROTO_TCP,TCP_NODELAY,(const?? char*)&bNodelayt,sizeof(BOOL));??
? setsockopt(s,SOL_SOCKET,SO_DEBUG,(const?? char*)&bDebug,sizeof(BOOL));??
? 12.附加:往往通過setsockopt()設置了緩沖區大小,但還不能滿足數據的傳輸需求,??
? 我的習慣是自己寫個處理網絡緩沖的類,動態分配內存;下面我將這個類寫出,希望對??
? 初學者有所幫助:
??
?
Code//==============================================================================???
??//???二進制數據,主要用于收發網絡緩沖區的數據???
??//???CNetIOBuffer???以???MFC???類???CString???的源代碼作為藍本改寫而成,用法與???CString???類似,???
??//???但是???CNetIOBuffer???中存放的是純粹的二進制數據,'\0'???并不作為它的結束標志。???
??//???其數據長度可以通過???GetLength()???獲得,緩沖區地址可以通過運算符???LPBYTE???獲得。???
????
????
??//==============================================================================???
??//?????Copyright???(c)???All-Vision???Corporation.???All???rights???reserved.???
??//?????Module:?????NetObject???
??//?????File:?????????SimpleIOBuffer.h???
??//?????Author:?????gdy119???
??//?????Email???:?????8751webmaster@126.com???
??//?????Date:???????2004.11.26???
??//==============================================================================???
??//???NetIOBuffer.h???
??#ifndef???_NETIOBUFFER_H???
??#define???_NETIOBUFFER_H???
??//=============================================================================???
??#define?????MAX_BUFFER_LENGTH?????1024*1024???
??//=============================================================================???
??//主要用來處理網絡緩沖的數據???
??class?????CNetIOBuffer???????
??{???
??protected:???
??LPBYTE?????????????????????????????m_pbinData;???
??int???????????????????????????????????m_nLength;???
??int???????????????????????????????????m_nTotalLength;???
??CRITICAL_SECTION?m_cs;???
??????????void?????Initvalibers();???
??public:???
??CNetIOBuffer();???
??CNetIOBuffer(const???LPBYTE???lbbyte,???int???nLength);???
??CNetIOBuffer(const???CNetIOBuffer&binarySrc);???
??virtual???~CNetIOBuffer();???
??//=============================================================================???
??BOOL?????????????CopyData(const???LPBYTE???lbbyte,???int???nLength);???
??BOOL?????????????ConcatData(const???LPBYTE???lbbyte,???int???nLength);???
??void?????????????ResetIoBuffer();???
??int???????????????GetLength()???const;???
??BOOL?????????????SetLength(int???nLen);???
??LPBYTE???????????GetCurPos();???
??int???????????????GetRemainLen();???
??BOOL?????????????IsEmpty()???const;???
??operator???????LPBYTE()???const;???
??static?????????GetMaxLength()???{???return???MAX_BUFFER_LENGTH;???}???
??const???CNetIOBuffer&???operator=(const???CNetIOBuffer&???buffSrc);???
??};???
??#endif???//?????
??//???NetOBuffer.cpp:???implementation???of???the???CNetIOBuffer???class.???
??//======================================================================???
??#include???"stdafx.h"???
??#include???"NetIOBuffer.h"???
??//======================================================================???
??//=======================================================================???
??//???Construction/Destruction???
??CNetIOBuffer::CNetIOBuffer()???
??{???
??Initvalibers();???
????
??}???
??CNetIOBuffer::CNetIOBuffer(const???LPBYTE???lbbyte,???int???nLength)???
??{???
??Initvalibers();???
??CopyData(lbbyte,???nLength);???
??}???
??CNetIOBuffer::~CNetIOBuffer()???
??{???
??delete???[]m_pbinData;???
????????m_pbinData=NULL;???
????????DeleteCriticalSection(&m_cs);???
????
??}???
??CNetIOBuffer::CNetIOBuffer(const???CNetIOBuffer&binarySrc)???
??{???
????
????????Initvalibers();???
????????CopyData(binarySrc,binarySrc.GetLength());???
????
??}???
??void???CNetIOBuffer::Initvalibers()???
??{???
????
??m_pbinData???????????=???NULL;???
??m_nLength?????????????=???0;???
??m_nTotalLength???=???MAX_BUFFER_LENGTH;???
??if(m_pbinData==NULL)???
??{???
??m_pbinData=new???BYTE[m_nTotalLength];???
??ASSERT(m_pbinData!=NULL);???
??}???
??InitializeCriticalSection(&m_cs);???
??}???
??void???CNetIOBuffer::ResetIoBuffer()???
??{???
??EnterCriticalSection(&m_cs);???
??m_nLength???=???0;???
??memset(m_pbinData,0,m_nTotalLength);???
??LeaveCriticalSection(&m_cs);???
??}???
????
??BOOL???CNetIOBuffer::CopyData(const???LPBYTE???lbbyte,???int???nLength)???
??{???
??if(???nLength???>???MAX_BUFFER_LENGTH???)???
??return???FALSE;???
????
??ResetIoBuffer();???
??EnterCriticalSection(&m_cs);???
??memcpy(m_pbinData,???lbbyte,???nLength???);???
??m_nLength???=???nLength;???
??LeaveCriticalSection(&m_cs);???
????
??return???TRUE;???
??}???
????
??BOOL???CNetIOBuffer::ConcatData(const???LPBYTE???lbbyte,???int???nLength)???
??{???
??if(???m_nLength???+???nLength???>???MAX_BUFFER_LENGTH???)???
??return???FALSE;???
????
??EnterCriticalSection(&m_cs);???
??memcpy(m_pbinData+m_nLength,???lbbyte,???nLength???);???
??m_nLength???+=???nLength;???
??LeaveCriticalSection(&m_cs);???
????
??return???TRUE;???
??}???
????
??int???CNetIOBuffer::GetLength()???const???
??{???
??return???m_nLength;???
??}???
????
??BOOL???CNetIOBuffer::SetLength(int???nLen)???
??{???
??if(???nLen???>???MAX_BUFFER_LENGTH???)???
??return???FALSE;???
????
??EnterCriticalSection(&m_cs);???
??m_nLength???=???nLen;???
??LeaveCriticalSection(&m_cs);???
????
??return???TRUE;???
??}???
????
??LPBYTE???CNetIOBuffer::GetCurPos()???
??{???
????
??if(???m_nLength???<???MAX_BUFFER_LENGTH???)???
????
??return???(m_pbinData+m_nLength);???
????
??else???
??return???NULL;???
??}???
????
??CNetIOBuffer::operator???LPBYTE()???const???
??{???
??return???m_pbinData;???
??}???
????
??int???CNetIOBuffer::GetRemainLen()???
??{???
????
??????return???MAX_BUFFER_LENGTH???-???m_nLength;???
????
??}???
??BOOL???CNetIOBuffer::IsEmpty()???const???
??{???
??return???m_nLength???==???0;???
??}???
????
??const???CNetIOBuffer&???CNetIOBuffer::operator=(const???CNetIOBuffer&???buffSrc)???
??{???
??if(&buffSrc!=this)???
??{???
??CopyData(buffSrc,???buffSrc.GetLength());???
????
??}???
??????return???*this;???
????
??}?
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/gxj1680/archive/2009/01/06/3722145.aspx
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/gxj1680/archive/2009/01/06/3722145.aspx
轉載于:https://www.cnblogs.com/duzouzhe/archive/2009/06/16/1504214.html
總結
以上是生活随笔為你收集整理的setsockopt()用法(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MTK点亮新模组
- 下一篇: MongoDB学习笔记(一) Mongo