setsockopt()用法(转载)
1.?? 如果在已經(jīng)處于?? ESTABLISHED狀態(tài)下的socket(一般由端口號(hào)和標(biāo)志符區(qū)分)調(diào)用??
? closesocket(一般不會(huì)立即關(guān)閉而經(jīng)歷TIME_WAIT的過(guò)程)后想繼續(xù)重用該socket:??
? BOOL?? bReuseaddr=TRUE;??
? setsockopt(s,SOL_SOCKET?? ,SO_REUSEADDR,(const?? char*)&bReuseaddr,sizeof(BOOL));??
? 2.?? 如果要已經(jīng)處于連接狀態(tài)的soket在調(diào)用closesocket后強(qiáng)制關(guān)閉,不經(jīng)歷??
? TIME_WAIT的過(guò)程:??
? BOOL???? bDontLinger?? =?? FALSE;????
? setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const?? char*)&bDontLinger,sizeof(BOOL));??
? 3.在send(),recv()過(guò)程中有時(shí)由于網(wǎng)絡(luò)狀況等原因,發(fā)收不能預(yù)期進(jìn)行,而設(shè)置收發(fā)時(shí)限:??
? int?? nNetTimeout=1000;//1秒??
? //發(fā)送時(shí)限??
? setsockopt(socket,SOL_S0CKET,SO_SNDTIMEO,(char?? *)&nNetTimeout,sizeof(int));??
? //接收時(shí)限??
??? setsockopt(socket,SOL_S0CKET,SO_RCVTIMEO,(char?? *)&nNetTimeout,sizeof(int));??
? 4.在send()的時(shí)候,返回的是實(shí)際發(fā)送出去的字節(jié)(同步)或發(fā)送到socket緩沖區(qū)的字節(jié)??
? (異步);系統(tǒng)默認(rèn)的狀態(tài)發(fā)送和接收一次為8688字節(jié)(約為8.5K);在實(shí)際的過(guò)程中發(fā)送數(shù)據(jù)??
? 和接收數(shù)據(jù)量比較大,可以設(shè)置socket緩沖區(qū),而避免了send(),recv()不斷的循環(huán)收發(fā):??
? //?? 接收緩沖區(qū)??
? int?? nRecvBuf=32*1024;//設(shè)置為32K??
? setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const?? char*)&nRecvBuf,sizeof(int));??
? //發(fā)送緩沖區(qū)??
? int?? nSendBuf=32*1024;//設(shè)置為32K??
? setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const?? char*)&nSendBuf,sizeof(int));??
? 5.?? 如果在發(fā)送數(shù)據(jù)的時(shí),希望不經(jīng)歷由系統(tǒng)緩沖區(qū)到socket緩沖區(qū)的拷貝而影響??
? 程序的性能:??
? int?? nZero=0;??
? setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char?? *)&nZero,sizeof(nZero));??
? 6.同上在recv()完成上述功能(默認(rèn)情況是將socket緩沖區(qū)的內(nèi)容拷貝到系統(tǒng)緩沖區(qū)):??
? int?? nZero=0;??
? setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char?? *)&nZero,sizeof(int));??
? 7.一般在發(fā)送UDP數(shù)據(jù)報(bào)的時(shí)候,希望該socket發(fā)送的數(shù)據(jù)具有廣播特性:??
? BOOL???? bBroadcast=TRUE;????
? setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const?? char*)&bBroadcast,sizeof(BOOL));??
? 8.在client連接服務(wù)器過(guò)程中,如果處于非阻塞模式下的socket在connect()的過(guò)程中可??
? 以設(shè)置connect()延時(shí),直到accpet()被呼叫(本函數(shù)設(shè)置只有在非阻塞的過(guò)程中有顯著的??
? 作用,在阻塞的函數(shù)調(diào)用中作用不大)??
? BOOL?? bConditionalAccept=TRUE;??
? setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const?? char*)&bConditionalAccept,sizeof(BOOL));??
? 9.如果在發(fā)送數(shù)據(jù)的過(guò)程中(send()沒(méi)有完成,還有數(shù)據(jù)沒(méi)發(fā)送)而調(diào)用了closesocket(),以前我們??
? 一般采取的措施是"從容關(guān)閉"shutdown(s,SD_BOTH),但是數(shù)據(jù)是肯定丟失了,如何設(shè)置讓程序滿足具體??
? 應(yīng)用的要求(即讓沒(méi)發(fā)完的數(shù)據(jù)發(fā)送出去后在關(guān)閉socket)???
? struct?? linger?? {??
????? u_short???????? l_onoff;??
????? u_short???????? l_linger;??
? };??
? linger?? m_sLinger;??
? m_sLinger.l_onoff=1;//(在closesocket()調(diào)用,但是還有數(shù)據(jù)沒(méi)發(fā)送完畢的時(shí)候容許逗留)??
? //?? 如果m_sLinger.l_onoff=0;則功能和2.)作用相同;??
? m_sLinger.l_linger=5;//(容許逗留的時(shí)間為5秒)??
? setsockopt(s,SOL_SOCKET,SO_LINGER,(const?? char*)&m_sLinger,sizeof(linger));??
? Note:1.在設(shè)置了逗留延時(shí),用于一個(gè)非阻塞的socket是作用不大的,最好不用;??
??????????? 2.如果想要程序不經(jīng)歷SO_LINGER需要設(shè)置SO_DONTLINGER,或者設(shè)置l_onoff=0;??
? 10.還一個(gè)用的比較少的是在SDI或者是Dialog的程序中,可以記錄socket的調(diào)試信息:??
? (前不久做過(guò)這個(gè)函數(shù)的測(cè)試,調(diào)式信息可以保存,包括socket建立時(shí)候的參數(shù),采用的??
? 具體協(xié)議,以及出錯(cuò)的代碼都可以記錄下來(lái))??
? BOOL?? bDebug=TRUE;??
? 11.發(fā)送數(shù)據(jù)時(shí)候一般是系統(tǒng)緩沖區(qū)滿以后才發(fā)送,現(xiàn)在設(shè)置為只要系統(tǒng)??
? 緩沖區(qū)有數(shù)據(jù)就立刻發(fā)送:??????
? 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.附加:往往通過(guò)setsockopt()設(shè)置了緩沖區(qū)大小,但還不能滿足數(shù)據(jù)的傳輸需求,??
? 我的習(xí)慣是自己寫個(gè)處理網(wǎng)絡(luò)緩沖的類,動(dòng)態(tài)分配內(nèi)存;下面我將這個(gè)類寫出,希望對(duì)??
? 初學(xué)者有所幫助:
??
?
Code//==============================================================================???
??//???二進(jìn)制數(shù)據(jù),主要用于收發(fā)網(wǎng)絡(luò)緩沖區(qū)的數(shù)據(jù)???
??//???CNetIOBuffer???以???MFC???類???CString???的源代碼作為藍(lán)本改寫而成,用法與???CString???類似,???
??//???但是???CNetIOBuffer???中存放的是純粹的二進(jìn)制數(shù)據(jù),'\0'???并不作為它的結(jié)束標(biāo)志。???
??//???其數(shù)據(jù)長(zhǎng)度可以通過(guò)???GetLength()???獲得,緩沖區(qū)地址可以通過(guò)運(yùn)算符???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???
??//=============================================================================???
??//主要用來(lái)處理網(wǎng)絡(luò)緩沖的數(shù)據(jù)???
??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;???
????
??}?
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/gxj1680/archive/2009/01/06/3722145.aspx
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/gxj1680/archive/2009/01/06/3722145.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/duzouzhe/archive/2009/06/16/1504214.html
總結(jié)
以上是生活随笔為你收集整理的setsockopt()用法(转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MTK点亮新模组
- 下一篇: MongoDB学习笔记(一) Mongo