日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Windsock套接字I/O模型学习 --- 第二章

發布時間:2024/8/26 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windsock套接字I/O模型学习 --- 第二章 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. select模型

select模型主要借助于apiselect來實現,所以先介紹一下select函數

int select( int nfds, // 忽略,僅是為了與 Berkeley 套接字兼容 fd_set* readfds, // 指向一個套接字集合,用來檢查其可讀性 fd_set* writefds, // 指向一個套接字集合,用來檢查其可寫性 fd_set* exceptfds, // 指向一個套接字集合,用來檢查錯誤 const struct timeval* timeout // 指定此函數等待的最長時間,如果為 NULL,則最長時間為無限大 );// fd_set結構體 typedef struct fd_set { u_int fd_count; // 下面數組的大小 SOCKET fd_array[FD_SETSIZE]; // 套接字句柄數組 } fd_set;FD_ZERO(*set) //初始化 set 為空集合。集合在使用前應該總是清空 FD_CLR(s, *set) //從 set 移除套接字 s FD_ISSET(s, *set) //檢查 s 是不是 set 的成員,如果是返回 TRUE FD_SET(s, *set) //添加套接字到集合

2.例子

一個簡單的流程:

  • 初始化套接字集合 fdSocket,向這個集合添加監聽套接字句柄。
  • 將 fdSocket 集合的拷貝 fdRead 傳遞給 select 函數,當有事件發生時, select 函數移除 fdRead 集合中沒有未決 I/O 操作的套接字句柄,然后返回。
  • 比較原來 fdSocket 集合與 select 處理過的 fdRead 集合,確定哪些套接字有未決 I/O,并進一步處理這些 I/O。
  • 回到第 2 步繼續進行選擇處理。
  • CInitSock theSock; // 初始化 Winsock 庫 int main() {USHORT nPort = 4567; // 此服務器監聽的端口號// 創建監聽套接字SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(nPort);sin.sin_addr.S_un.S_addr = INADDR_ANY;// 綁定套接字到本地機器if (::bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR){printf(" Failed bind() \n");return -1;}// 進入監聽模式::listen(sListen, 5);// select 模型處理過程// 1)初始化一個套接字集合 fdSocket,添加監聽套接字句柄到這個集合fd_set fdSocket; // 所有可用套接字集合FD_ZERO(&fdSocket);FD_SET(sListen, &fdSocket);while (TRUE){ // 2)將 fdSocket 集合的一個拷貝 fdRead 傳遞給 select 函數,// 當有事件發生時, select 函數移除 fdRead 集合中沒有未決 I/O 操作的套接字句柄,然后返回。fd_set fdRead = fdSocket;int nRet = ::select(0, &fdRead, NULL, NULL, NULL);if (nRet > 0){ // 3)通過將原來 fdSocket 集合與 select 處理過的 fdRead 集合比較,// 確定都有哪些套接字有未決 I/O,并進一步處理這些 I/O。for (int i = 0; i < (int)fdSocket.fd_count; i++){if (FD_ISSET(fdSocket.fd_array[i], &fdRead)){if (fdSocket.fd_array[i] == sListen) // ( 1)監聽套接字接收到新連接{if (fdSocket.fd_count < FD_SETSIZE){sockaddr_in addrRemote;int nAddrLen = sizeof(addrRemote);SOCKET sNew =::accept(sListen, (SOCKADDR*)&addrRemote, &nAddrLen);FD_SET(sNew, &fdSocket);printf("接收到連接( %s) \n", ::inet_ntoa(addrRemote.sin_addr));}else{printf(" Too much connections! \n");continue;}}else{char szText[256];int nRecv = ::recv(fdSocket.fd_array[i], szText, strlen(szText), 0);if (nRecv > 0) // ( 2)可讀{szText[nRecv] = '\0';printf("接收到數據: %s \n", szText);}else // ( 3)連接關閉、重啟或者中斷{::closesocket(fdSocket.fd_array[i]);FD_CLR(fdSocket.fd_array[i], &fdSocket);}}}}}else{printf(" Failed select() \n");break;}}return 0; }

    3.好處

    使用 select 的好處是程序能夠在單個線程內同時處理多個套接字連接,這避免了阻塞模
    式下的線程膨脹問題。但是,添加到 fd_set 結構的套接字數量是有限制的,默認情況下,最
    大值是 FD_SETSIZE,它在 winsock2.h 文件中定義為 64。為了增加套接字數量,應用程序可
    以將 FD_SETSIZE 定義為更大的值(這個定義必須在包含 winsock2.h 之前出現)。不過,自
    定義的值也不能超過 Winsock 下層提供者的限制(通常是 1024)

    轉載于:https://www.cnblogs.com/zjzyh/p/5459581.html

    總結

    以上是生活随笔為你收集整理的Windsock套接字I/O模型学习 --- 第二章的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。