<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 閱讀(651) 評論(0)  編輯  收藏 所屬分類: C++
    主站蜘蛛池模板: 亚洲第一页综合图片自拍| 最新中文字幕电影免费观看| 99视频精品全部免费观看| 1区2区3区产品乱码免费| 久久不见久久见中文字幕免费| 在线免费一区二区| 国产成人精品曰本亚洲79ren| 亚洲AV综合色区无码一区| 亚洲成a人不卡在线观看| 亚洲精品无码久久久久牙蜜区| 日韩电影免费在线观看网址| 久久精品免费观看| 国产啪精品视频网免费| 免费国产成人午夜电影| 亚洲国产精品无码久久久秋霞2 | 亚洲精品动漫免费二区| 一级**爱片免费视频| 久久这里只精品热免费99| 成人奭片免费观看| 亚洲国产免费综合| 亚洲高清中文字幕| 精品国产日韩亚洲一区91| 免费看黄的成人APP| 在线看片无码永久免费视频| 无码欧精品亚洲日韩一区夜夜嗨 | 中文字幕视频免费| 日韩午夜免费视频| 国产V亚洲V天堂无码| 亚洲人成网站在线在线观看| 国产免费一级高清淫曰本片| 国产精品69白浆在线观看免费| 亚洲精品国产高清嫩草影院| 亚洲高清日韩精品第一区| 美国毛片亚洲社区在线观看| 无码人妻精品中文字幕免费| 日本不卡免费新一二三区| 亚洲激情中文字幕| 黄色一级视频免费观看| 日韩人妻一区二区三区免费| 国产免费小视频在线观看| 久久久久亚洲精品日久生情|