程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> WinSock編程基礎,winsock編程

WinSock編程基礎,winsock編程

編輯:C++入門知識

WinSock編程基礎,winsock編程


一、套接字模式

  1、阻塞模式

      創建套接字時,默認是阻塞模式,對recv函數調用會使程序進入等待狀態,知道接收到數據才返回。

  2、非阻塞模式:

     可以調用ioctlsocket函數顯式地讓套接字工作在非阻塞模式下。

u_long ul = 1;
    SOCKET s = ::socket(AF_INET,SOCK_STREAM,0);
    ::ioctlsocket(s,FIONBIO,(u_long*)&ul);

3、windows提供的I/O模型

    1、Select模型

           使用select函數來管理I/O

#include "../../common/InitSock.h"
#include <stdio.h>

CInitSock initsock;

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){
                            szText[nRecv] = '\n';
                            printf("接收到數據:%s",szText);
                        }else{ //連接關閉 重啟或中斷
                            ::closesocket(fdsocket.fd_array[i]);
                            FD_CLR(fdsocket.fd_array[i],&fdsocket);
                        }
                    }
                }
            }
        }else{
            printf("Failed select()\n");
            break;
        }
    }
    
    return 0;
}

   

    2、WSAAsyncSelect模型

        WSAAsyncSelect模型允許應用程序以windows消息的形式接受到網絡時間通知。 MFC的CSocket也是該模型。

        (為適應windows的消息驅動環境而設置的,現在許多對性能要求不高的網絡應用程序都采用WSAASyncSelect模型)

    3、WSAEventSelect模型

    4、重疊(Overlapped)I/O模型

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved