<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 495,comments - 227,trackbacks - 0

    服務端套接字是編程最簡單的一個部分,甚至在各種環境下都可以用類似的代碼。對于一個服務端套接字而言,他的基本工作包括:

    1. 初始化
    2. 創建套接字
    3. 給套接字捆綁一個本地地址
    4. 【可選】設置套接字屬性
    5. 調用listen函數
    6. 進入accept循環,接受來自客戶端的請求
    7. 對PCS進行管理
    8. 釋放服務端套接字所占用的資源

    3.1 初始化

    對于每個需要處理套接字的程序,在調用任何其他套接字函數之前,必須首先調用WSAStartup函數。如果不調用它,其他函數調用會失敗,并返回WSANOTINITIALISED錯誤碼,表示WinSock庫還沒有初始化。對于除了其他操作系統,初始化的方法會不一樣,請參見對應的文檔找到初始化方法。

    WSAStartup的函數原型為:

    int WSAStartup(
    WORD wVersionRequested,
    LPWSADATA lpWSAData
    );

    其中,各個參數的含義如下:
    wVersionRequested: 本程序所需要的最低版本號。請注意,MSDN中所說的是本程序可能用到的最高版本的函數,其含義和我所說的一樣。
    lpWSAData 返回WSADATA結構,說明WinSock庫當前的實現細節

    該函數成功時返回0,否則可能返回如下一些錯誤碼:
    WSASYSNOTREADY 底層網絡系統未準備好
    WSAVERNOTSUPPORTED 所要求版本號本實現不支持
    WSAEINPROGRESS 一個阻塞性套接字操作未完成
    WSAEPROCLIM 達到當前實現所支持的最大任務數
    WSAEFAULT lpWSAData是一個非法指針

    一般用戶并不關心實現細節,只要當前實現庫滿足最低版本需求即可。常見代碼為:

     WORD wVersion = MAKEWORD(2,2);//最低版本2.2
    WSADATA WSAData;
    int nResult;
    if(ERROR_SUCCESS != (nResult = WSAStartup(wVersion,&WSAData)))
    {
    ReportError("WSAStartup", nResult);
    return -1;
    }

    3.2 創建套接字

    每個套接字任務都從創建套接字開始。我們可以用socket函數來創建套接字,該函數的原型為:

    SOCKET socket(
    int af,
    int type,
    int protocol
    )
    其中,各個參數的含義為: 協議號,說明該套接字所處理的協議。他的可選值隨前面兩個參數不同而不同。似乎在RAW協議中用的比較多,大家可以在ROUTPROT.h中找到類似定義。
    af 地址族,說明該socket支持的地址類型。我們可以在winsock2.h中找到所支持的地址族。不過一般來說,對于TCP/IP編程,我們都會設置為AF_INET
    type 協議類型,Winsock2.h中列出了5種類型,我們一般會使用其中的三種,SOCK_STREAM表示流協議,SOCK_DGRAM表示數據報協議,SOCK_RAW表示原始套接字。我會在數據傳輸部分詳細解釋這些內容
    protocol

    用于偵聽的套接字需要是流套接字,下面代碼會創建這樣的套接字:

        SOCKET hSocket;
    int a = PROTO_ICMP;
    hSocket = socket(AF_INET,SOCK_STREAM,0);
    if(ERRORHANDLE(hSocket == INVALID_SOCKET))
    {
    WSACleanup();
    return -1;
    }

    3.3 捆綁本地地址

    每個套接字必須有一個地址才能和對方通訊。bind函數用于捆綁地址,它的函數原型為:

    int bind(
    SOCKET s,
    const struct sockaddr* name,
    int namelen
    );

    各個參數含義如下:
    s 套接字號
    name 地址信息:需要注意的是,套接字接口是給多種協議共享的,sockaddr結構只是一個占位符,不同協議使用不同的地址結構,例如,TCP/IP編程使用的結構是sockaddr_in
    namelen 地址結構的長度,加入這個參數的原因也就是因為不同協議有不同的結構

    需要注意的,bind函數只能給socket綁定本機的IP地址,如果你給出的地址信息是其他機器的,則必然會失敗。此時該函數返回SOCKET_ERROR,WSAGetLastError則返回WSAEADDRNOTAVAIL。

    如果沒有特殊需求,應該設置該結構的IP地址為INADDR_ANY。對于端口,服務端套接字需要指定一個端口,而客戶端端口最好設置為0,讓系統選擇一個可用端口。

    下面代碼初始化一個地址結構:

    void InitializeAddress(DWORD ip, UINT port, sockaddr_in & addr)
    {
    memset(&addr,0,sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr= ip;
    addr.sin_port = htons(port);
    }

    下面代碼則把一個套接字綁定到本機2000端口上:

    if(ERRORHANDLE(SOCKET_ERROR == bind(hSocket, (const sockaddr*) & addr, sizeof(addr)))) 
    {
    closesocket(hSocket);
    WSACleanup();
    return -1;
    }

    3.4 進入偵聽狀態

    當我們創建一個套接字,并綁定了地址后,我們需要設置這個套接字進入偵聽狀態,進入偵聽狀態后,該套接字就可以處理來自客戶端的鏈接請求。

    listen函數設置套接字進入偵聽狀態,其函數原型為:

    int listen(
    SOCKET s,
    int backlog
    );

    對于剛開始編程的人,最容易誤解的是backlog參數。許多人以為這就是該套接字最多能接收的鏈接的數目。實際上,一個套接字能接受的鏈接的數目不受這個參數控制,它只受系統資源的限制。例如對于linux,套接字用文件句柄實現,那么它可能受最大文件句柄數的限制。

    這個參數的含義是最多未決連接的數目,也就是連接請求已經到了服務端套接字,但是用戶還沒有調用accept的套接字數目。對于WinSock2,這個參數最大值為5。

    下面示例代碼說明了如何調用listen:

    if(ERRORHANDLE(SOCKET_ERROR == listen(hSocket,5))) 
    {
    closesocket(hSocket);
    WSACleanup();
    return -1;
    }

    3.5 accept循環

    當一個套接字處于偵聽狀態以后,我們就可以循環調用accept來接受新連接。accept函數的原型如下:

    SOCKET accept(
    SOCKET s,
    struct sockaddr* addr,
    int* addrlen
    );

    這個函數的參數說明和前面bind的一樣。需要說明的是,在MSDN中說后面兩個參數都是out參數,經過我的測試,結論并不一樣。對于 addrlen參數,應該是一個in/out參數,也就是說,如果第二個參數是一個結構指針,則第三個參數必須是一個整型變量的指針,該整型變量還必須被 設置為該結構的長度。

    3.6 PCS管理

    由于一個一個服務端套接字可能接收無數個PCS,如何管理這些PCS就成為一個問題。不同的程序員有自己不同的管理方式,在此我就不準備細講了。

    posted on 2008-07-03 15:17 SIMONE 閱讀(652) 評論(0)  編輯  收藏 所屬分類: C++
    主站蜘蛛池模板: 中文字幕无码成人免费视频| 免费国产污网站在线观看15| 日韩激情无码免费毛片| 亚洲视频免费观看| 9277手机在线视频观看免费| 久久久久亚洲精品美女| a级毛片视频免费观看| 亚洲夜夜欢A∨一区二区三区| GOGOGO高清免费看韩国| 亚洲精品无码久久久影院相关影片| 国产免费一区二区三区免费视频| 中文字幕亚洲无线码| 免费无遮挡无遮羞在线看 | 中美日韩在线网免费毛片视频| 亚洲福利在线播放| 中文字幕不卡免费高清视频| 亚洲成在人线av| 1000部无遮挡拍拍拍免费视频观看| 亚洲精品自拍视频| 18禁超污无遮挡无码免费网站国产 | 亚洲中文字幕伊人久久无码| 在线免费观看h片| 91情国产l精品国产亚洲区| 国产免费久久精品99re丫y| 亚洲午夜无码久久| 亚洲天堂中文字幕在线| a级毛片免费高清毛片视频| 亚洲精品成人图区| 在线观看亚洲免费视频| 国产免费久久久久久无码| 久久亚洲sm情趣捆绑调教| 一级女人18毛片免费| 免费夜色污私人影院网站电影| 亚洲国产精品乱码一区二区| aa级一级天堂片免费观看| 日本黄页网址在线看免费不卡| 亚洲av无码一区二区三区不卡 | 国产成人+综合亚洲+天堂| 亚洲国产精品无码久久久不卡 | 国产综合免费精品久久久| 亚洲福利电影在线观看|