1. 程式人生 > >Linux C網路程式設計的一點總結

Linux C網路程式設計的一點總結

以下僅個人總結,望網友指正。

我做的是,實現客戶端與客戶端之間互相通訊,這樣也算基本搭起來了,之前也做過一個即時通訊軟體的專案,現在溫習一下,所以點到為止。

1.      網路結構的標準模型是OSI模型,由ISO國際網際網路標準化組織定義的網路分層模型。

2.      ISO/OSI七層網路模型:應用層---表示層---會話層---傳輸層---網路層---資料鏈路層---網路層

3.      TCP/IP四層參考模型:應用層---傳輸層----網路互聯層---主機到網路

4.      ARP(地址解析協議):完成IP地址和硬體地址的對應關係。

客戶端/伺服器網路程式設計注意點

伺服器端

1.      首先建立套接字,呼叫的函式為socket(),引數使用的一般為IPv4 Internet協議,和套接字型別為流式套接字(套接字的型別有:流式套接字(SOCK_STREAM),資料報套接字(SOCK_DGRAM)(主要用於UDP連線)及原始套接字  ),流式套接字用於TCP連線,提供序列化的,可靠的,雙向連線的位元組流。

2.      在建立套接字成功以後,也就是得到了套接字的id,這時候就可以開始bind(),對套接字地址和埠進行繫結,才能進行資料的接收和傳送。

3.      繫結函式中,使用的第一個引數為套接字fd,第二個為一個套接字的地址結構,那麼相對於AF_INET的域,我們使用結構體struct sockaddr_in這個結構體     

4.       struct sockaddr_in{ 
       short int            sin_family; /* 地址族 */ 
       unsigned short int      sin_port;/* 埠號 */ 
       struct in_addr            sin_addr; /*IP地址 */ 
       unsigned char           sin_zero[8]; /*填充0 以保持與struct sockaddr同樣大小 */ 
       }; 

struct sockaddr { 
        unsignedshort       sa_family; /* 地址族, AF_xxx */ 
            char                       sa_data[14]; /* 14 位元組的協議地址 */
          }; 

5.      好處在於,這個結構體可以在第四個成員中填充0,使之與scokaddr結構體一樣大小,這樣就可以完成兩種結構體的型別的轉換。

6.      下一步就是將這個結構體清空,然後在裡面填充重要的網路資訊,有域,埠和ip地址,埠和ip地址需要使用函式進行轉化,比如:埠需要使用htons()將埠的位元組順序轉化為網路的位元組順序(大端儲存),因為主機的位元組順序有時候大端有時候小端,然後還有一個inet_addr()函式,使用這個函式,將例如192.168.1.1這樣的字串ip地址轉化為二進位制資料給結構體,讓繫結的時候能夠正確辨識。

7.      接下來是監聽,也就是listen(),引數為套接字的fd和設定的監聽佇列的長度。

8.      再就是開始迴圈的接收accept(),這個函式有一個特點,就是接收完了,那麼這時候會返回一個新的套接字,這個新的套接字就是客戶端連線請求是客戶端的套接字檔案描述符fd,然後舊的,也就是原來伺服器建立的那個套接字還是在不斷的監聽和接收,新的套接字就可以通過send()和recv()函式,再新的套接字基礎上進行資料的收發。

9.      在accept成功以後,就要在伺服器端開啟一個執行緒,這樣就可以單獨的去處理某一個客戶端的請求操作。

10.  這時候可以使用傳參的方式,把新的客戶端的套接字進行傳入給執行緒的執行單元,這樣就能讓執行緒依靠這個套接字描述符進行和該客戶端的通訊了。

11.  那麼如何通訊呢?我們使用不帶緩衝的IO操作,write和read,進行對套接字為檔案描述符的操作,反正Linux下皆為檔案。

12.  這時候出現一個問題,就是阻塞問題,阻塞是一般我們自己寫伺服器和客戶端使用的方法,因為比較好用,也比較能夠理清邏輯,但是我覺得阻塞是不合理的,不能讓執行緒停在一個地方。所以這個問題需要考慮。

13.  第二個問題就是如何實現訊號的處理,如何將組合鍵讓伺服器獲取,然後做出正確的退出等操作。

客戶端

1.      首先建立套接字

2.      然後使用套接字進行連線connect(),如果連線上了伺服器就可以開始做客戶端做的操作了。

3.      客戶端的操作可以放在一個函式中,這個函式中為迴圈的做一件事情,可以使用輪詢的方式,不斷的write和read,這樣達到了阻塞型的客戶端。

4.      阻塞問題這是問題,需要解決,但是阻塞有阻塞的壞處,不阻塞也有不阻塞的壞處。