windowssocket程式設計注意以下幾點!
1. 如果在已經處於established狀態下的socket(一般由埠號和標誌符區分)呼叫closesocket(一般不會立即關閉而經歷time_wait的過程)後想繼續重用該socket:
bool breuseaddr=true;
setsockopt(s,sol_socket ,so_reuseaddr,(constchar*)&breuseaddr,sizeof(bool));
2.如果要已經處於連線狀態的soket在呼叫closesocket後強制關閉,不經歷time_wait的過程:
bool bdontlinger =false;
setsockopt(s,sol_socket,so_dontlinger,(constchar*)&bdontlinger,sizeof(bool));
3.在send(),recv()過程中有時由於網路狀況等原因,發收不能預期進行,而設定收發時限:
intnnettimeout=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()不斷的迴圈收發:
// 接收緩衝區
intnrecvbuf=32*1024;//設定為32k
setsockopt(s,sol_socket,so_rcvbuf,(constchar*)&nrecvbuf,sizeof(int));
//傳送緩衝區
intnsendbuf=32*1024;//設定為32k
setsockopt(s,sol_socket,so_sndbuf,(constchar*)&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傳送的資料具有廣播特性:
boolbbroadcast=true;
setsockopt(s,sol_socket,so_broadcast,(constchar*)&bbroadcast,sizeof(bool));
8.在client連線伺服器過程中,如果處於非阻塞模式下的socket在connect()的過程中可以設定connect()延時,直到accpet()被呼叫(本函式設定只有在非阻塞的過程中有顯著的作用,在阻塞的函式呼叫中作用不大)
boolbconditionalaccept=true;
setsockopt(s,sol_socket,so_conditional_accept,(constchar*)&bconditionalaccept,sizeof(bool));
9.如果在傳送資料的過程中(send()沒有完成,還有資料沒傳送)而呼叫了closesocket(),以前我們一般採取的措施是"從容關閉"shutdown(s,sd_both),但是資料是肯定丟失了,如何設定讓程式滿足具體應用的要求(即讓沒發完的資料傳送出去後在關閉socket)?
struct 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,(constchar*)&m_slinger,sizeof(linger));
note:1.在設定了逗留延時,用於乙個非阻塞的socket是作用不大的,最好不用;
2.如果想要程式不經歷so_linger需要設定so_dontlinger,或者設定l_onoff=0;
10.還乙個用的比較少的是在sdi或者是dialog的程式中,可以記錄socket的除錯資訊:
(注:這個函式可以儲存調式資訊,包括socket建立時候的引數,採用的
具體協議,以及出錯的**都可以記錄下來)
bool bdebug=true;
setsockopt(s,sol_socket,so_debug,(constchar*)&bdebug,sizeof(bool));
11.在用到acceptex函式需要注意的是,在通過wsaioctl獲取acceptex函式指標時,只需要傳遞給wsaioctl乙個有效的socket即可,該socket的型別不會影響獲取的acceptex函式指標。
如果不希望acceptex建立連線後等待使用者傳送資料,那麼必須將第四個引數設為0。第5、6引數必須是對應socket的位址型別的大小再加上16個位元組。
為了使伺服器能較好的處理使用者連線請求,可採取如下兩種策略:
策略一.設定兩個界限值,使系統未處理的accept操作保持在乙個固定水平。推薦上限為10;
策略二.通過wsaeventselect函式監聽listensocket上的fd_accept事件。
當關閉完成埠時,如果還有未處理的accepte操作,應該先關閉listensocket,然後在iocp中,處理這些accept操作(進行資源釋放等),切記不要強行終止那些沒有處理的accept操作,否則會造成記憶體洩漏。
為防止惡意使用者(建立連線後,不傳送資料),可設定listensocket的so_connect_time屬性。
如果希望clientsocket具有和listensocket相同的屬性,需要對clientsocket呼叫so_update_accept_context。
Windows Socket 程式設計
伺服器端 客戶端 在 http fayaa.com code 處理的高亮顯示效果 c 語言 臨時自用 include include void main if lobyte wsadata wversion 1 hibyte wsadata wversion 1 socket socksrv soc...
Windows Socket程式設計
windows下socket程式設計主要包括以下幾部分 服務端1 初始化windows socket庫。2 建立socket。3 繫結socket。4 監聽。5 accept。6 接收 傳送資料。客戶端1 初始化windows socket庫。2 建立socket。3 連線socket。4 接收 傳...
Windows Socket程式設計
1 初始化windows socket庫。2 建立socket。3 繫結socket。4 監聽。5 accept。6 接收 傳送資料。1 初始化windows socket庫。2 建立socket。3 連線socket。4 接收 傳送資料。服務端每接收到乙個客戶端的socket,則建立乙個執行緒。滿...