-windows CE網路編程備忘錄(原創)

來源:互聯網
上載者:User

 

1    在windows CE5.0中不支援WSAAsyncSelect函數,這個函數調用後會自動將通訊端(可能是Socket的音譯)設定成為 非阻塞模式,並向winsock Dll 註冊一個或幾個感興趣的事件(FD_CLOSE...),並提供一個通知時使用的視窗控制代碼,當註冊的網路事件發生時,對應的視窗將收到一個基於訊息的通知,就可以寫處理代碼了。

替代函數可以使用select或者WSAEventSelect,其中WSAEventSelect和WSAAsyncSelect的最大區別是網路事件會被發送到一個事件物件控點,而不是發送到一個視窗。

這個WSAEventSelect要求2.0的winsock版本:Requirements

  Version: Requires Windows Sockets 1.1 or later.
  Header: Declared in Winsock2.h.
  Library: Use Ws2_32.lib.

2   select函數可以用於阻塞和非阻塞IO中,也就是說調用了select後不會自動將通訊端設定成非阻塞模式,該是什麼模式就是什麼模式,其實也沒什麼,如果是阻塞模式,也不會阻塞在recv函數處,而是阻塞在select函數處,但select有逾時退出機制,使用timeval來確定等待的事件,退出後就可以幹別的事情了,幹完了回來繼續阻塞在select處。採用一個while(1)即可。

3   網路函數中,所以關係到收發資料的緩衝都屬於簡單的char類型,也就是說,這些函數沒有沒有“Unicode”版本,使用Unicode的時候需要把想發送的字串當成char*或者乾脆把它轉換成為char*發送:在利用字串長度函數告訴winsock API函數收發的資料有多少字元時,需要乘以2,因為---每個字元佔用字串數組的兩個位元組。此外也可以在將字串資料賦給Winsock API前,用WideCharToMultiByte把UNICODE轉換成ASCii碼。在我的windowCE程式中我採用後者,好處:網路傳輸的資料量少了二分之一。 

      由於沒有Uncode版本的winsock函數,於是當把_T("192.168.0.10")傳遞給connect函數,是可以編譯通過的,但是卻無法串連的上,呵呵,為了這個錯誤,費了好大氣力尋找。

4  先看一段節選自MSDN的關於WSAEnumNetworkEvents函數的解釋:

The socket's internal record of network events is copied to the structure referenced by lpNetworkEvents, after which the internal network events record is cleared. If the hEventObject parameter is not NULL, the indicated event object is also reset. The Windows Sockets provider guarantees that the operations of copying the network event record, clearing it and resetting any associated event object are automatic, such that the next occurrence of a nominated network event will cause the event object to become set. In the case of this function returning SOCKET_ERROR, the associated event object is not reset and the record of network events is not cleared.

這裡邊值得注意的是最後一句話。

5  if (networkEvents.lNetworkEvents & FD_CLOSE)
  {
   if (0 != networkEvents.iErrorCode[FD_CLOSE_BIT])
   {
    ::PostMessage((HWND)lpParameter, WM_SERVER_MESSAGE, 0, 2);
   }
   else
   {
    ::PostMessage((HWND)lpParameter, WM_SERVER_MESSAGE, 0, 1);
    getpeername(g_Socks[index - WSA_WAIT_EVENT_0],(sockaddr*)&name,&namelen);
    //closesocket(g_Socks[index - WSA_WAIT_EVENT_0]); //加上這句話會進入死迴圈
   }
   
  }

不知道為什麼使用closesocket總是出現問題,如果加上這一句會出現FD_CLOSE無法清除或者反覆由系統發出(搞不清是哪種情況,但傾向於後者)而導致死迴圈的問題。

6  while(1)
 {
  if( TRUE == g_bQuit )
   break;

  index = WSAWaitForMultipleEvents(g_NumOfEvents, g_Events, /
          FALSE, WSA_INFINITE/*TIMEOUT_USECS*/, FALSE);
  TRACE(_T("index:%d/tg_NumOfEvents:%d/n"), index, g_NumOfEvents);

此處如果用TIMEOUT_USECS會發生產生無限多個FD_ACCEPT的情況而導致死迴圈。這個沒搞清楚是怎麼回事

7  int res = recv(g_Socks[index - WSA_WAIT_EVENT_0], pbuf, BUF_SIZE, 0);
   if (res > 0)
   {
    pbuf += res;
    if (TCPIP_DATA_LENGTH == pbuf - buf) //此處的重大缺陷是如果接收到的資料一次或者累計(未恰好達到TCPIP_DATA_LENGTH)超過TCPIP_DATA_LENGTH,則永遠無法顯示
    {
     buf[TCPIP_DATA_LENGTH] = '/0';

     g_csNet.Lock();

     memcpy(g_buf, buf, sizeof(buf));

write by xiaoxiongli未完。。。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.