




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Windows Socket網絡編程(二)套接字編程原理作者:冰點工作室小鷹參一、客戶機/服務器模式在TCP/IP網絡中兩個進程間的相互作用的主機模式是客戶機/服務器模式(Client/Server model) 。該模式的建立基于以下兩點:1、非對等作用;2、通信完全是異步的。客戶機/服務器模式在操作過程中采取的是主動請示方式:首先服務器方要先啟動,并根據請示提供相應服務:(過程如下)1、打開一通信通道并告知本地主機,它愿意在某一個公認地址上接收客戶請求。2、等待客戶請求到達該端口。3、接收到重復服務請求,處理該請求并發送應答信號。4、返回第二步,等待另一客戶請求5、關閉服務器。客戶方:1、
2、打開一通信通道,并連接到服務器所在主機的特定端口。2、向服務器發送服務請求報文,等待并接收應答;繼續提出請求3、請求結束后關閉通信通道并終止。4二、基本套接字為了更好說明套接字編程原理,給出幾個基本的套接字,在以后的篇幅中會給出 更詳細的使用說明。1、 創建套接字socket。功能:使用前創建一個新的套接字格式:SOCKET PASCAL FAR socket(int af,int type,int procotol);參數:af:通信發生的區域type:要建立的套接字類型procotol:使用 的特定協議2、指定本地地址bind()功能:將套接字地址與所創建的套接字號聯系起來。格式:int
3、PASCAL FAR bind(SOCKET s,const struct sockaddr FAR * name,intn amele n);參數:s:是由socket()調用返回的并且未作連接的套接字描述符(套接字號)。其它:沒有錯誤,bind()返回0,否則SOCKET_ERROR地址結構說明:struct sockaddr_i nshort sin_family;/AF_INET u_short sin_port;/16位 端 口 號 , 網 絡 字 節 順 序struct in_addr sin_addr;/32位 IP 地 址 , 網 絡 字 節 順 序char sin_zero8
4、;/ 保 留3 、 建 立 套 接 字 連 接 connect() 和 accept() 功能:共同完成連接工作格 式 : int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR * name,int namelen);SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen);參數:同上4、監 聽 連 接 listen() 功能:用于面向連接服務器,表明它愿意接收連接。格 式 : int PASCAL FAR listen(SOCKE
5、T s, int backlog);5、數 據 傳 輸 send() 與 recv() 功能:數據的發送與接收 格 式 : int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags); int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags);參 數 : buf: 指 向 存 有 傳 輸 數 據 的 緩 沖 區 的 指 針 。6、多 路 復 用 select() 功能:用來檢測一個或多個套接字狀態。格 式 : int PASCAL FAR
6、 select(int nfds,fd_set FAR * readfds,fd_set FAR *writefds,fd_set FAR * exceptfds,const struct timeval FAR * timeout);參 數 : readfds: 指 向 要 做 讀 檢 測 的 指 針 writefds: 指 向要做 寫檢測 的指針 exceptfds: 指 向 要 檢 測 是 否 出 錯 的 指 針 timeout: 最 大 等 待 時 間select()* 執行 同步 I/O 多路 復用。 select 函 數 的 參 數 ( int nfds, fd_set readf
7、ds, fd_set writefds, fd_set exceptfds, const struct timeval timeout )我記得是:第一個是個較為次要的值,設成 0 就行了。 后面的幾個 FD_SET 類 型的參數才是最重要的;第 一 個 FD_SET 型 的 參 數 readfds 是 表 示 要 被 檢 查 是 否 可 讀 的 Sockets ,把 你 想 要接收數據的那個套接字放在這里;第 二 個 FD_SET 參 數 ritefds 是 表 示 要 被 檢 查 是 否 可 寫 的 Sockets , 將 你 要 發 送 數據的套接字放在這里;還 有 個 FD_SET 參
8、 數 exceptfds 是 表 示 要 被 檢 查 是 否 有 錯 誤 的 Sockets select()函數的第五個參數timeout ,是讓我們用來設定select 函數要等待(block )多 久。茲述說如下:( 1)如 果 timeout 設為 NULL ,那 么 select() 就會一直等到 至少某 一 個 socket的 事 件 成 立 了 才 會 return , 這 和 其 他 的 blocking 函 數 一 樣 。select( ., NULL )( 2)如 果 timeout的 值 設為 0, 0( 秒 , 微秒),那 么 select()在檢 查后,不管有沒 有
9、socket的 事件成立 , 都會 馬上 return , 而不會 停留。timeout.tv_sec = timeout.tv_usec = 0; select( ., &timeout )( 3)如果 timout 設為 m, n ,那么就會等到至少某一個 socket 的 事件發 生, 或是時間到了( m 秒 n 微秒), 才會 return 。 timeout.tv_sec = m;timeout.tv_usec = n; select( ., &timeout )返回值:成 功 - 符合條件的 Sockets 總數 (若 Timeout 發生,則 為 0) 失敗- S
10、OCKET_ERROR ( 呼 叫 WSAGetLastError() 可 得 知 原 因 )說明: 使用者可利用此函式來檢查 Sockets 是否有資料可被讀取,或是有空間 可以寫入, 或是有錯誤發生。關 于 對 FD_SET 類 型 的 操 作 ,有 幾 個 比 較 重 要 的 宏 : FD_ZERO(*set) - 將 set 的 值清乾 凈 FD_SET(s, *set) - 將 s 加到 set 中 FD_CLR(s, *set) - 將 s 從 set 中刪除 FD_ISSET(s, *set) - 檢查 s 是否 存在於 set 中 參數 readfds 、 writefds 、
11、及 exceptfds 都 是 called by value- result ;而 called by value-result的意思就是說,我們在將參數傳給系統時,要先設啟始值,并 將這些參數的位址(address )告訴系統;而系統則會利用到這些值來做些運算 或其他用途,最后并將結果再寫回這些參數的位址中。 因此這些參數的值在傳 入前和函數返回后,可能會不同;所以每次調用select() 前,對這些參數一定 要重新設定它們的值。假設我們要檢查socket 1 和2目前是否可以用來傳送 資料,以及socket 3 是 否有資料可讀;我們不打算檢查sockets 是否有錯誤 發生,所以 ex
12、ceptfds 設為 NULL。步驟大致 如下: FD_ZERO( &writefds );FD_ZERO( & readfds ); FD_SET( 1, &writefds ); FD_SET( 2, &writefds );FD_SET( 3, & readfds ); select( ., & readfds, &writefds, NULL, .) if(FD_ISSET( 1, &writefds ) send( 1, data ); if (FD_ISSET( 2, &writefds )send( 2, d
13、ata ); if (FD_ISSET( 3, & readfds ) recv( 3, data );7、關閉套接字closesocket()功能:關閉套接字s格式:BOOL PASCAL FAR closesocket(SOCKET s);冷三、典型過程圖2.1面向連接的套接字的系統調用時序圖2.2無連接協議的套接字調用時序圖2.3面向連接的應用程序流程圖FD_ZERO , FD_ISSET 這些 都是套節字結合 操作宏看 看 MSDN 上 的 select函數,這是在 selectio模型中的 核心,用來管理套節字 IO 的 ,避免出現無辜鎖定.intselect(intnfds
14、,fd_setFAR*readfds,fd_setFAR*writefds,fd_setFAR*exceptfds,conststructtimevalFAR*timeout);第一個參數不管,是兼容目的,最后的是超時標準select是阻塞操作 當然要設置超時事件.接著的 三個類型為 fd_set 的 參數分別是用于檢查套節字的 可讀性 ,可寫性,和 列外數據性質.我舉個例子比如 recv(), 在沒有數據到來調用它的 時 候,你的 線程將被阻塞 如果數 據一直不來,你的 線程就要阻塞很久.這樣顯然不 好. 所以采用 select 來查看套節字是否可讀(也就是 是否有數據讀了) 步驟如下soc
15、ket s;fd_set set;while(1)FD_ZERO(&set);/ 將 你的 套節 字集合 清空FD_SET(s, &set);/ 加入你感興趣 的 套節字到集合,這里是一個 讀數據 的 套 節 字 sselect(0,&set,NULL,NULL,NULL);/檢查套節字是 否可讀,/ 很 多 情況下就是是否有數據(注意,只是說很多情況)/ 這 里 select 是 否 出 錯 沒 有 寫if(FD_ISSET(s,&set) / 檢查 s 是否在這個集合里面,/select 將 更 新這個集合,把其中不可讀的 套節字去掉/ 只 保 留 符 合
16、條件的 套節字在這個集合里面recv(s,.);/dosomethinghere不知道你現在 明白沒 有.另 ,由于 這段時間沒忙 這,有 錯誤不 負責任.呵呵.1、 Socket 服務器端:Socket 服務器端流程如下:加載套接字->創建監聽的套接字 ->綁定套接字 ->監聽套接字 ->處理客戶端相關請求。下面是孫鑫 VC 詳解里面的服務器端的例子:C+弋碼#include <Winsock2.h>#include <stdio.h>void main()/ 加載套接字WORD wVersionRequested;WSADATA wsaDat
17、a;int err;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if (err!=0)return;if (LOBYTE(wsaData.wVersion)!=1| HIBYTE(wsaData.wVersion)!=1)WSACleanup();return;/ 創建監聽的套接字SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(IN
18、ADDR_ANY);/ 把 U_LONG 的主機字節順序轉換為TCP/IP網絡字節順序addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000);/綁定套接字 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/將套接字設置為監聽模式,準備接受用戶請求 listen(sockSrv,5);SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);printf("%sn","welcome,the serve is s
19、tarted."); while (1)/ 等待用戶請求到來SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); char sendBuf100;tosprintf(sendBuf,"welcome %s ",inet_ntoa(addrClient.sin_addr);/ 發送數據 send(sockConn,sendBuf,100,0);char revBuf100;/ 接收數據 recv(sockConn,revBuf,100,0);/ 打印接受數據 printf("
20、;%sn",revBuf);/ 關閉套接字 closesocket(sockConn);#include <Winsock2.h>#include <stdio.h>void main()/ 加載套接字WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if (err!=0)return;if (LOBYTE(wsaData.wVersion)!=1|HIBYTE
21、(wsaData.wVersion)!=1)WSACleanup();return;/ 創建監聽的套接字SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/ 把 U_LONG 的主機字節順序轉換為TCP/IP網絡字節順序addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000);/綁定套接字 bind(sockSrv,(SOCKADDR*)&addrSrv,s
22、izeof(SOCKADDR);/將套接字設置為監聽模式,準備接受用戶請求 listen(sockSrv,5);SOCKADDR_IN addrClient;int len=sizeof(SOCKADDR);printf("%sn","welcome,the serve is started.");while (1)/ 等待用戶請求到來SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); char sendBuf100;tosprintf(sendBuf,"we
23、lcome %s ",inet_ntoa(addrClient.sin_addr);/ 發送數據 send(sockConn,sendBuf,100,0);char revBuf100;/ 接收數據 recv(sockConn,revBuf,100,0);/ 打印接受數據 printf("%sn",revBuf);/ 關閉套接字 closesocket(sockConn); 注意:需要包含頭文件 <Winsock2.h> ,并且在工程設置的 link 里面加上 ws32_2.dll 如果在 VC 中還有一個簡單的加載套接字的方法:C+弋碼if (!Af
24、xSocketInit()AfxMessageBox("套接字加載失敗!”);return false;if (!AfxSocketInit()AfxMessageBox("套接字加載失敗!”);return false;這個不需要包含上面注里面的頭文件和 ws2_32.lib 庫就可以實現加載套接字。 2、Socket 客戶端:Socket 客戶端同樣需要先加載套接字,然后創建套接字,不過之后不用綁定和監聽了,而是直接連接服務器,發送相關請求。同樣貼出孫鑫 VC 詳解里面的客戶端的例子: (不是我偷懶,是人家實在寫的太好,無法超 越)C+弋碼#include <Wi
25、nsock2.h>#include <stdio.h>void main() / 加載套接字WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if (err!=0)return;if (LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)WSACleanup(); return;/ 創建套接字SOCKET sockCl
26、ient=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=inet_addr(""); 把 U_LONG的主機字節順序轉換為 TCP/IP網絡字節順序addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000);/向服務器發送請求 connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/接受數據char recBuf100; recv(sockClient,recBuf,100,0);printf("%sn",recBuf);/發送數據 send(sockClient,"this is 扈修非 ",strlen("thi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 江蘇省南京聯合體【棲霞、江寧、雨花】重點達標名校2025年初三中考一模試卷化學試題含解析
- 湖南省長沙市瀏陽市2025屆數學三下期末綜合測試模擬試題含解析
- 寧夏葡萄酒與防沙治沙職業技術學院《大學英語Ⅱ(聽力)》2023-2024學年第二學期期末試卷
- 武漢紡織大學外經貿學院《新藥研究與開發A》2023-2024學年第一學期期末試卷
- 遼寧省沈陽市鐵西區達標名校2025年下學期初三生物試題中考仿真模擬考試試卷(四)含解析
- 內蒙古醫科大學《智能制造系統架構》2023-2024學年第二學期期末試卷
- 延安大學《木版畫術科技能教學》2023-2024學年第二學期期末試卷
- 湛江幼兒師范專科學校《口腔臨床醫學概論(口腔修復學)》2023-2024學年第一學期期末試卷
- 四川鐵道職業學院《鋼筋混凝土與砌體結構設計》2023-2024學年第二學期期末試卷
- 茅臺學院《英國維多利亞文學》2023-2024學年第二學期期末試卷
- 第三章基于數據驅動的故障診斷方法ppt課件
- T∕CAAA 030-2020 澳洲白綿羊種羊
- 微波-PATHLOSS軟件的應用-入門指導
- 藍牙音響成品檢驗規范
- 材料5:個人征信系統機構接入和接口驗收工作流程
- 項目選址比選方案分析參考范本
- 初三化學酸堿鹽的鑒別
- 學校總務采購業務流程圖(共1頁)
- 預制混凝土襯砌管片生產工藝技術規程doc
- 極域電子教室解決方案
- JA系列電子天平使用說明書
評論
0/150
提交評論