windows 網路編程經典入門的問題

來源:互聯網
上載者:User

我現在的情況是OnAccept()中的非同步事件註冊不成功,用WSAGetLastError()獲得的錯誤碼為0,用switch無法獲得錯誤訊息,下面是原代碼,My Code是在其基礎上完善的,架構大致是一樣的, 

 

其實我想知道的是accept參數中的Socket參數是用server(正在監聽的參數)還是用訊息映射函數從Windows中獲得的SOCKET pSock = (SOCKET)wParam 這個參數,我使用server時無法重新註冊非同步事件,但使用pSock卻可以,但我根本不知道用這個pSock取得的SOCKET對象是否是合法的,雖然註冊非同步事件成功,但用戶端中斷連線時,服務端仍無任何響應,IP_EVENT 事件我已重新註冊 

到訊息映射中去,用另一個訊息映射函數 IPEvent() 與其關聯,訊息映射是正常合法的 

 

 

#define NETWORK_EVENT USER_MESSAGE+100 //定義網路事件 

sockaddr_in clientaddr; file: //暫時存放用戶端IP地址 

 

//自己定義訊息映射函數,將上面定義的網路事件映射到處理函數 

//OnNetEvent為網路事件處理函數,它在下面定義 

ON_MESSAGE(NETWORK_EVENT, OnNetEvent); 

 

在你對話方塊中的初始化函數中調用下面的初始化網路的子函數 

BOOL InitNetwork() //初始化網路 

//初始化TCP協議 

BOOL ret = WSAStartup(MAKEWORD(2, 2), &wsaData); 

if (ret != 0) 

MessageBox("初始化通訊端失敗!"); 

return FALSE; 

 

//建立伺服器端通訊端 

SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

if (serverSocket == INVALID_SOCKET) 

MessageBox("建立通訊端失敗!"); 

closesocket(m_Socket); 

WSACleanup(); 

return FALSE; 

 

//綁定到本地一個連接埠上 

sockaddr_in localaddr; 

localaddr.sin_family = AF_INET; 

localaddr.sin_port = htons(1688); 

localaddr.sin_addr.s_addr = 0; 

if (bind(serverSocket , (const struct sockaddr*)&localaddr, 

sizeof(sockaddr)) == SOCKET_ERROR) 

MessageBox("綁定地址失敗!"); 

closesocket(m_Socket); 

WSACleanup(); 

return FALSE; 

 

//註冊網路非同步事件,m_hWnd為應用程式的主對話方塊或主視窗的控制代碼 

WSAAsyncSelect(serverSocket, m_hWnd, NETWORK_EVENT, 

FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE); 

 

listen(serverSocket, 5); //設定偵聽模式 

 

return TRUE; 

 

//定義網路事件的響應函數 

void OnNetEvent(WPARAM wParam, LPARAM lParam) 

//調用API函數,得到網路事件類型 

int iEvent = WSAGETSELECTEVENT(lParam); 

 

//得到發出此事件的用戶端通訊端 

SOCKET pSock = (SOCKET)wParam; 

 

switch (iEvent) 

case FD_ACCEPT: //用戶端串連請求 

OnAccept(); 

 

break; 

case FD_CLOSE: //用戶端斷開事件: 

OnClose(pSock); 

break; 

case FD_READ: //網路資料包到達事件 

OnReceive(pSock); 

break; 

case FD_WRITE: //發送網路資料事件 

OnSend(pSock); 

break; 

default: break; 

 

void OnAccept(SOCET pSock) //響應用戶端串連請求函數 

int len = sizeof(sockaddr); 

 

//調用API函數,接受串連,並返回一個新通訊端 

//還可以獲得用戶端的IP地址 

SOCKET clientSocket = accept(serverSocket, 

(struct sockaddr*) & clientaddr, &len); 

 

//為新的socket註冊非同步事件,注意沒有Accept事件 

if (WSAAsyncSelect(clientSocket , m_hWnd, IP_EVENT, 

FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR) 

MessageBox("註冊非同步事件失敗!"); 

return ; 

 

//自編函數,將此用戶端的相關資訊儲存下來:通訊端、 

// IP地址、登陸時間 

saveClientSocket(clientSocket, clientAddr,currentTimer); 

 

void OnClose(SOCET pSock) 

//自編函數,結束與相應的用戶端的通訊,釋放相應資源並做相應處理 

endClientSocket(pSock); 

 

void OnSend(SOCET pSock) 

//自編函數,在給用戶端發資料時做一些預先處理 

handleOnSend(pSock); 

 

void OnReceive(SOCET pSock) 

recv(); //調用API函數,讀出網路緩衝區中的資料包 

 

//自編函數,將此資料包和發出此資料的用戶端 

//clientSocket封裝成一條網路訊息 

buildNetMsg(); 

 

//自編函數,將此網路訊息放入一個訊息佇列中,由背景工作執行緒去處理 

saveNetMsg(); 

SetEvent(); //用事件對象觸發背景工作執行緒 

}  

相關文章

聯繫我們

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