windows網路程式設計經典入門 (轉)
對於一個初學者,下面方法是經典。
初學者建議不要用MFC提供的類,而用windows 做一個簡單和客戶端,這樣有助於對socket程式設計機制的理解。
為了簡單起見,應用是基於MFC的標準對話方塊。
Winsock用WINDOWS API實現:
(1)伺服器端有兩個執行緒:
主執行緒 — 你需要編寫以下來實現
#defineWORK_EVENT USER_MESSAGE+100 file://定義網路事件
sockaddr_in clientaddr; file://暫時存放客戶端
file://自己定義訊息對映函式,將上面定義的網路事件對映到處理函式
file://OnNetEvent為網路事件處理函式,它在下面定義
ON_MESSAGE(NETWORK_EVENT, OnNetEvent);
在你對話方塊中的初始化函式中下面的初始化網路的子函式
BOOL InitNetwork() file://初始化網路
{
file://初始化TCP
BOOL ret = Wtartup(MAKE(2,2), &wsaData);
if(ret != 0)
{
MessageBox("初始化套接字失敗!");
return FALSE;
}
file://建立伺服器端套接字
SOCKET serverSocket
= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(serverSocket == INVALID_SOCKET)
{
MessageBox("建立套接字失敗!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}
file://繫結到本地一個埠上
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;
}
file://註冊網路非同步事件,m_hWnd為應用程式的主對話方塊或主視窗的控制程式碼
WSAAsync(serverSocket, m_hWnd, NETWORK_EVENT,
FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);
listen(serverSocket, 5); file://設定偵聽
return TRUE;
}
file://定義網路事件的響應函式
void OnNetEvent(WPARAM wParam, LPARAM lParam)
{
file://呼叫API函式,得到網路事件型別
int iEvent = WSAGETSELECTEVENT(lParam);
file://得到發出此事件的客戶端套接字
SOCKET pSock = (SOCKET)wParam;
switch(iEvent)
{
case FD_ACCEPT: file://客戶端連線請求
{
OnAccept();
break;
}
case FD_CLOSE: file://客戶端斷開事件:
{
OnClose(pSock);
break;
}
case FD_READ: file://網路資料包到達事件
{
OnReceive(pSock);
break;
}
case FD_WRITE: file://傳送網路資料事件
{
OnSend(pSock);
break;
}
default: break;
}
}
void OnAccept(SOCET pSock) file://響應客戶端連線請求函式
{
int len = sizeof(sockaddr);
file://呼叫API函式,接受連線,並返回一個新套接字
file://還可以獲得客戶端的IP地址
SOCKET clientSocket = accept(serverSocket,
(struct sockaddr*)&clientaddr, &len);
file://為新的socket註冊非同步事件,注意沒有Accept事件
if(WSAAsyncSelect(clientSocket ,m_hWnd, IP_EVENT,
FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox("註冊非同步事件失敗!");
return;
}
file://自編函式,將此客戶端的相關資訊儲存下來:套接字、
// IP地址、登陸時間
saveClientSocket(clientSocket,clientAddr,currentTimer);
}
void OnClose(SOCET pSock)
{
file://自編函式,結束與相應的客戶端的通訊,釋放相應資源並做相應處理
endClientSocket(pSock);
}
void OnSend(SOCET pSock)
{
file://自編函式,在給客戶端發資料時做一些預處理
handleOnSend(pSock);
}
void OnReceive(SOCET pSock)
{
recv(...); file://呼叫API函式,讀出網路緩衝區中的資料包
file://自編函式,將此資料包和發出此資料的客戶端
file://clientSocket封裝成一條網路訊息
buildNetMsg(...);
file://自編函式,將此網路訊息放入一個訊息佇列中,由工作執行緒去處理
saveNetMsg(...);
SetEvent(...); file://用事件觸發工作執行緒
}
客戶端登陸後,隨即把自己的名發給伺服器,伺服器接到後,把它儲存下來。這樣伺服器就可以顯示所有線上客戶端的資訊了,包括:客戶端計算機名、IP地址、登陸時間等。
注意: 客戶端沒有OnAccept()函式,但有OnConnect()函式。
工作執行緒 —
在你的應用程式初始化時,建立並啟動一個工作執行緒
AfxBeginThread(WorkThread,this,THREAD_PRIORITY_NORMAL);
file://this可能為應用程式的主對話方塊或主視窗的控制程式碼
UINT WorkThread(LPVOID pParam)
{
while(1)
{
file://等待多重事件到來
int ret = WaitForMultiple(...);
switch(ret)
{
case OBJECT_0:
{
if(bNewNetMsg) file://檢視網路訊息佇列是否有新的網路訊息
{
readNetMsg(...); file://如有新的網路訊息,則讀出
handleNetMsg(...); file://處理此網路訊息
}
break;
}
case OBJECT_0 + 1:
{
file://做退出處理
break;
}
default: break;
}
return 0;
}
客戶端為單執行緒,登陸伺服器時,用connect()函式給伺服器發連線請求;
客戶端沒有OnAccept()函式,但有OnConnect()函式。
在OnConnect()函式里做發連線請求時的預處理;
在OnReceive()函式里響應並處理網路資料;
在OnClose()函式里響應伺服器的關閉事件;
在OnSend()函式里做發資料時的預處理;
如果你還想實現各客戶端之間的線上交流(即所謂的室),你在客戶端還可以基於UDP協議
再做一套多點對多點的組播模型模型,以後在和你聊,你先把上面的程式實現。
以上的I/O非同步模型基於Windows的訊息機制,另外還可以用事件模型、重疊模型或完成埠模型,
建議你參考Windows網路程式設計指南之類的書。
如果你能對上面的機制很熟練,你肯定已經對Winsock編網路程式的機制有一定理解,接下來你可以進行更精彩的程式設計, 不僅可以在網輸普通資料,而且還
以傳輸語音、影片資料,你還可以自己做一個聊天室,和你的同學在實驗室的區域網裡可以共同分享你的成果。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1007830/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 神經網路程式設計入門【轉】神經網路程式設計
- Python網路程式設計(基礎總結入門經典)Python程式設計
- JavaScript函數語言程式設計入門經典JavaScript函數程式設計
- [轉]BI入門經典
- BI入門經典 (轉)
- C語言程式設計入門經典18個小程式C語言程式設計
- Python程式設計入門——基礎語法詳解(經典)Python程式設計
- 網站設計:600個經典網站... (轉)網站
- Linux學習路線及網路程式設計經典書籍(轉載)Linux程式設計
- C#網路程式設計經典程式碼C#程式設計
- (三)神經網路入門之隱藏層設計神經網路
- 經典程式設計引言程式設計
- Windows經典妙招(轉)Windows
- Linux網路程式設計入門 (轉載)Linux程式設計
- Webpack經典入門Web
- TCSHshell程式設計入門(轉)程式設計
- 遊戲開發新手入門之Windows程式設計(轉)遊戲開發Windows程式設計
- 神經網路入門神經網路
- 程式設計和網路程式設計入門程式設計
- C++入門經典第一章程式設計專案C++程式設計
- 《Flutter 入門經典》之“Flutter 入門 ”Flutter
- Kafka入門經典教程Kafka
- 聊聊經典機器學習入門機器學習
- 圖神經網路入門神經網路
- 計算機網路經典20問!計算機網路
- Windows 輸入法程式設計 (上) (轉)Windows程式設計
- 經典程式設計書籍大全程式設計
- Linux程式設計入門-crypt(轉)Linux程式設計
- Python程式設計入門(1) (轉)Python程式設計
- Python程式設計入門(3) (轉)Python程式設計
- Python程式設計入門(4) (轉)Python程式設計
- Python程式設計入門(6) (轉)Python程式設計
- Python程式設計入門(7) (轉)Python程式設計
- Python程式設計入門(8) (轉)Python程式設計
- 程式設計“初學者”入門指南 (轉)程式設計
- Linux程式設計入門-gpm(轉)Linux程式設計
- Linux程式設計入門 - crypt(轉)Linux程式設計
- 程式語言入門經典案例【Python版】Python