Socket重疊IO

來源:互聯網
上載者:User

標籤:

1.為什麼到現在才弄懂這個

不知道這個Socket重疊IO這種模型是不是socket IO完成連接埠的基礎,不過我感覺,學習一下這個再去學習socket IO完成連接埠是比較有好處的。

這個Scoket重疊IO我以前記得看過好幾次,都沒看懂。一部分原因是我沒能靜態心來寫代碼,還有更重要的原因就是,Socket重疊他們的結構體參數,還有傳參數讓人很難理解。下面我將對這些資料結構和參數進行一下講解

2.初識WSARecv 函數

 

int WSARecv(        SOCKET s,//要接收訊息的socket        LPWSABUF lpBuffers, //一個結構體數組。當接收IO操作完畢後接收內容就在這個裡面了        DWORD dwBufferCount, //要接多少個WSABUF        LPDWORD lpNumberOfBytesRecvd,//接收了多少個位元組        LPDWORD lpFlags,        LPWSAOVERLAPPED lpOverlapped,//Overlapped結構體指標        LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine//在本節用不用        );

lpBuffers參數:這是一WSABUF數組,意思是這個函數可以接收不止一個字元緩衝,但是我們一般用一個就夠了。 接收多個我還沒能測試

dwBufferCount參數:是指上一個參數的數組個數

lpOverlapped參數:這個參數是Overlappad結構體指標,這個指標當IO操作完畢的時候,這裡會被系統填充。當IO操作完成時這個結構也可以通過WSAGetOverlappedResult得到

傳回值:

0:沒有錯誤發生,IO操作當即完成

SOCKET_ERROR:發生錯誤

如果是SOCKET_ERROR並且WSAGetLastError() == WSA_IO_PENDING 這時表示操作已經提交。非同步作業大部分都是這樣的。

3.何時得到收取的訊息,然後取出訊息

當異常操作完成時,Overlapped的hEvent這個事件會觸發。這時Overlapped的InternalHigh表示接受的位元組數。Internal表示錯誤碼。訊息的內容即是你當初調用WSARecv時傳入的lpBuffers參數。

4.程式碼群組織

以服務端為例

首先傳入WSARecv的幾個參數必定與一個socket關聯。而且這些參數在非同步呼叫完成之後,但是以後還要用(在WaitForMutiObjects時要用到),而且每一個socket得擁有一個不同的Event來標識是哪個用戶端來訊息了。所以為每一個用戶端socket構造一個Overlapped結構。比如我測試的代碼中每一個用戶端都有這樣一個結構體,而且當accept來的時候表示有新的socket串連,就得產生這樣一個結構體,當用戶端掉線的時候,就得刪除這樣一個結構體

下面就是這個結構體:

struct CClientInfo{public:    CClientInfo()     {        ZeroMemory(&m_ol,sizeof(m_ol));        ZeroMemory(m_szBuf,256);        m_ol.hEvent = WSACreateEvent();    }    ~CClientInfo()    {        WSACloseEvent(m_ol.hEvent);    }    WSAOVERLAPPED m_ol;    SOCKET sSocket;    CString strIp;    u_short nPort;    CString GetShowText();    char m_szBuf[256];};

 

下面是兩個函數,一個是當用戶端串連的時候,一個是當用戶端斷開的時候

CClientInfo * CServerDlg::OnSocketConnected(SOCKET sClientSocket,sockaddr_in * saClient){    u_short uPort =  ntohs(((sockaddr_in *)saClient)->sin_port);    CString strIp = CA2T(inet_ntoa(((sockaddr_in *)saClient)->sin_addr));    CClientInfo * pClientInfo = new CClientInfo;    pClientInfo->nPort = uPort;    pClientInfo->strIp = strIp;    pClientInfo->sSocket = sClientSocket;    LockClientArray();    m_ClientArray.Add(pClientInfo);    int nIndexInserted = m_ClientListBox.AddString(pClientInfo->GetShowText());    m_ClientListBox.SetItemData(nIndexInserted,pClientInfo->sSocket);    UnLockClientArray();    return pClientInfo;}void CServerDlg::OnSocketDisconnect(SOCKET aClientSocket){    LockClientArray();    for(int i = 0;i<m_ClientArray.GetCount();i++)    {        CClientInfo * pClientInfo = m_ClientArray.GetAt(i);        if(pClientInfo->sSocket == aClientSocket)        {            m_ClientListBox.DeleteString(m_ClientListBox.FindString(0,pClientInfo->GetShowText()));            delete pClientInfo;            m_ClientArray.RemoveAt(i);            break;        }    }    UnLockClientArray();}
5.沒有測試的內容和疑問

如果WSARecv調用兩次會是什麼情況,有沒有影響。

我沒有用非同步AcceptEx,感覺這個函數非同步了,作用也不大,以後如果需要的話,再學習吧

發送的時候沒有用WSASend,以後再學習

Socket重疊IO

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.