本文實現的功能類似於我之前所寫的一篇博文(Linux之select系統調用_2),區別在於進程之間的通信方式有所不同。之前的文章中,我所使用的是管道,而本文我將會使用socket接口。
客戶端發送消息給服務器,服務器收到消息後,會轉發該消息給所有客戶端。
1. server端維護一個鏈表,用於存放客戶端的聯系方式。結構如下:
typedef struct sockaddr_in SA ; typedef struct client_tag { SA ct_addr; struct client_tag* ct_next; }CNODE, *pcNODE;
2. 服務器創建一個socket端口,用於接收客戶端發送的消息。消息類別分為:通知上線,通知下線,以及聊天信息。因為消息類別不同,我們使用結構體將客戶端發送的消息進行如下封裝:
#define TYPE_ON 1 #define TYPE_OFF 2 #define TYPE_CHAT 3
#define SIZE 1024
typedef struct msg_tag { int msg_type; int msg_len; /* 實際消息長度 */ char msg_buf[SIZE]; }MSG, *pMSG;
注意,服務器所創建的socket端口需要綁定自己的聯系方式,以便其他客戶端可以發消息(sendto函數)給服務器。
3. 服務器使用select輪詢函數監聽自己的socket端口。當返回值為0(輪詢時間內沒有客戶端發消息)或者-1(收到信號,出錯)時,繼續輪詢;當返回值為1時,說明有客戶端發送消息。我們可以從recvfrom函數的傳出參數中獲取客戶端的聯系方式,此時根據收到的MSG類型,進行處理。如果MSG類型為上線,則將該客戶端的聯系方式加入鏈表;如果MSG類型為下線,則將其從鏈表中刪除;如果MSG類型為聊天信息,則服務器將其轉發給所有客戶端。
明天再說吧,大哥哥要先看火影了。
C/C++基礎
linux基礎:鳥哥的linux私房菜
計算機網絡
UNIX環境高級編程
希望對你有點幫助。
△
IGMP