1. 程式人生 > >[Linux C程式設計]網路通訊

[Linux C程式設計]網路通訊

網路通訊

1.簡述OSI的七層協議模型以及TCP/IP的四層協議模型

OSI七層模型:應用層、表示層、會話層、傳輸層、網路層、資料鏈路層、物理層

TCP/IP(Linux)四層模型:應用層,傳輸層,網路層,網路介面層

 

2.簡述TCP/IP各層的作用

(1)網路介面層(Network Interface Layer):網路介面層是TCP/IP協議軟體的最底層,負責將二進位制流轉換為資料幀,並進行資料幀的傳送和接收。資料幀是網路傳輸的基本單元

(2)網路層(Internet Layer)網路層負責在主機之間的通訊中選擇資料報的傳輸路徑,即路由。當網路層接收到傳輸層的請求後,傳輸某個具有目的地址資訊的分組。該層把分組封裝在IP資料報中,填入資料報的首部,使用路由演算法來確定是直接交付資料報,還是把它傳遞給路由器,然後把資料報交給適當的網路介面進行傳輸。

網路層還要負責處理傳入的資料報,檢驗其有效性,使用路由演算法來決定應該對資料報進行本地處理還是應該轉發。

如果資料報的目的機處於本機所在的網路,該層軟體就會除去資料報的首部,再選擇適當的運輸層協議來處理這個分組。最後,網路層還要根據需要發出和接收ICMP(Internet控制報文協議)差錯和控制報文。

(3)傳輸層(Transport Layer)傳輸層負責提供應用程式之間的通訊服務。這種通訊又稱為端到端通訊。傳輸層要系統地管理資訊的流動,還要提供可靠的傳輸服務,以確保資料到達無差錯、無亂序。為了達到這個目的,傳輸層協議軟體要進行協商,讓接收方回送確認資訊及讓傳送方重發丟失的分組。傳輸層協議軟體把要傳輸的資料流劃分為分組,把每個分組連同目的地址交給網路層去傳送。

(4)應用層(Application Layer)應用層是分層模型的最高層,在這個最高層中,使用者呼叫應用程式通過TCP/IP網際網路來訪問可行的服務。與各個傳輸層協議互動的應用程式負責接收和傳送資料。每個應用程式選擇適當的傳輸服務型別,把資料按照傳輸層的格式要求封裝好向下層傳輸。

3.TCP/IP各層的協議


第一部分稱為網路層。主要包括Internet 協議(IP)、網際控制報文協議(ICMP)和地址解析協議(ARP)

Internet 協議(IP)

 該協議被設計成互聯分組交換通訊網,以形成一個網際通訊環境。它負責在源主機和目的地主機之間傳輸來自其較高層軟體的稱為資料報文的資料塊,它在源和目的地之間提供非連線型傳遞服務

網際控制報文協議(ICMP)

 它實際上不是IP層部分,但直接同IP層一起工作,報告網路上的某些出錯情況。允許網際路由器傳輸差錯資訊或測試報文。

地址解析協議(ARP)

ARP 實際上不是網路層部分,它處於IP和資料鏈路層之間,它是在32位IP地址和48位實體地址之間執行翻譯的協議

第二部分是傳輸層協議,包括傳輸控制協議和使用者資料報文協議

傳輸控制協議(TCP):

該協議對建立網路上使用者程序之間的對話負責,它確保程序之間的可靠通訊,所提供的功能如下:

1.監聽輸入對話建立請求

2.請求另一網路站點對話

3.可靠的傳送和接收資料

4.適度的關閉對話

TCP是重要的傳輸層協議,目的是允許資料同網路上的其他節點進行可靠的交換。它能提供埠編號的譯碼,以識別主機的應用程式,而且完成資料的可靠傳輸TCP 協議具有嚴格的內裝差錯檢驗演算法確保資料的完整性TCP 是面向位元組的順序協議,這意味著包內的每個位元組被分配一個順序編號,並分配給每包一個順序編號

使用者資料報文協議(UDP):

UDP 提供不可靠的非連線型傳輸層服務,它允許在源和目的地之間傳送資料,而不必在傳送資料之前建立對話。它主要用於那些非連線型的應用程式,如:視訊點播

UDP也是傳輸層協議,它是無連線的,不可靠的傳輸服務.當接收資料時它不向傳送方提供確認資訊,它不提供輸入包的順序,如果出現丟失包或重份包的情況,也不會向傳送方發出差錯報文.由於它執行功能時具有較低的開銷,因而執行速度比TCP快

 

4.請簡述TCP/IP的三次握手的過程

第一步(A->B):主機A向主機B傳送一個包含SYN即同步(Synchronize)標誌的TCP報文,SYN同步報文會指明客戶端使用的埠以及TCP連線的初始序號;

第二步(B->A):主機B在收到客戶端的SYN報文後,將返回一個SYN+ACK的報文,表示主機B的請求被接受,同時TCP序號被加一,ACK即確認(Acknowledgement)。

第三步(A->B):主機A也返回一個確認報文ACK給伺服器端,同樣TCP序列號被加一,到此一個TCP連線完成

5.TCP和UDP如何選擇?

協議的選擇應該考慮到資料可靠性、應用的實時性和網路的可靠性。

·對資料可靠性要求高的應用需選擇TCP協議,而對資料的可靠性要求不那麼高的應用可選

擇UDP傳送。

·TCP協議中的3次握手、重傳確認等手段可以保證資料傳輸的可靠性,但使用TCP協議會

有較大的時延,因此不適合對實時性要求較高的應用;而UDP協議則有很好的實時性。

·網路狀況不是很好的情況下需選用TCP協議(如在廣域網等情況),網路狀況很好的情況

下選擇UDP協議可以減少網路負荷。

6.TCP、UDP的程式設計模型

 


7.Linux TCP網路程式設計函式

socket:建立一個socket套接字

bind:繫結IP地址和埠地址到socket

connect:該函式用於繫結之後的客戶端到伺服器連線

listen:設定能處理的最大連線要求

accept:接收socket連線

send:傳送資料

recv:接收資料

(1)socket

函式的作用:建立一個新的socket套接字

函式的原型:int socket(int domain,int type,int protocol)

函式的引數:domain:表示使用何種地址型別 AF_INET IPV4

                           AF_INET6 IPV6網路協議

        type:SOCK_STREAM :TCP 面向資料流提供可靠的、面向連線的通訊流

           SOCK_DGRAM:UDP 使用不連續不可信賴的資料包連線

           SOCK_RAM:提供原始網路協議,協議測試

        protocol:指定socket傳輸協議編號,設為0即可

返回值:成功返回socket套接字描述符,失敗-1

標頭檔案:#include<sys/socket.h>

(2)bind

函式的作用:繫結IP地址

函式的原型:int bind(int sockfd,struct sockaddr* my_addr,int addrlen)

函式的引數:sockfd:套接字描述符

        my_addr:主機地址        

        struct sockaddr

        {

         u_short sa_family;

         char sa_data[14];

        };

        struct sockaddr_in

        {

           short int sin_family;  /* Internet地址族 */

           unsigned short int sin_port;  /* 埠號 */

           struct in_addr sin_addr;   /* IP地址 */

           unsigned char sin_zero[8];  /* 填0 */

        };

       addrlen:sockaddr的地址長度

返回值:成功0 出錯-1

標頭檔案:#include <sys/types.h>

     #include <sys/socket.h>

(3)connect

函式的作用:建立socket連線的,通常客戶端連線伺服器使用

函式的原型:int connect(int sockfd,struct sockaddr* serv_addr,int addrlen)

函式的引數:serv_addr:表示要連線的伺服器IP地址

        addrlen:struct sockaddr的長度

返回值:成功0,出錯-1

(4)listen

函式的作用:聆聽網路,等待連線

函式的原型:int listen(int sockfd,int backlog)

函式的引數:sockfd:套接字描述符

        backlog:允許接入的客戶端數目

注意:listen並沒有連線,只是設定socket的listen模式,真正連線的accept

返回值:成功0 出錯 -1

(5)accept

函式的作用:接收網路連線,客戶端連線,三次握手在這

函式的原型:int send(int sockfd,struct sockaddr * addr, int * addrlen)

函式的引數:addr:連線成功,填充遠端客戶端的地址

       addrlen:struct sockaddr的長度

返回值:成功返回新的fd,失敗-1

(6)send

函式的作用:經過socket傳送資料,向對方傳送資料

函式的原型:int send(int sock_fd,const void *msg,int len,unsigned int flags)

函式的引數: sock_fd:accept建立起來的socket連線描述符,連線遠方的IP地址

        msg:傳送的資料

        len:資料長度

        flags:設為0

返回值:成功是實際傳送出去的位元組數,出錯-1

(7)recv

函式的作用:經過socket接收資料

函式的原型:int recv(int sock_fd,void * buf, int len,unsigned flag);

函式的引數: sock_fd:accept以後socket套接字描述符

        buf:存放地址

        len:接收資料的最大長度

返回值:成功返回接收的位元組數,失敗-1

8.位元組序轉換函式

不同型別的 CPU 對變數的位元組儲存順序可能不同:有的系統是高位在前,低位在後,而有的系統是低位在前,高位在後,而網路傳輸的資料順序是一定要統一的。所以當內部位元組儲存順序和網路位元組順序不同時,就一定要進行轉換

網路位元組順序採用大端排序方式

標頭檔案:#include <arpa/inet.h>

從主機發送到網路(整型資料):

uint32_t htonl(uint32_t hostlong);   //32位資料傳送,從主機傳送到網路

uint16_t htons(uint16_t hostshort);  //16位資料傳送,從主機到網路

從網路到主機:

uint32_t ntohl(uint32_t netlong);   //32位的資料接收,從網路到主機

int16_t ntohs(uint16_t netshort);   //16位的資料接收,從網路到主機

  這些函式名很好記,h表示host,n表示network,l表示32位長整數,s表示16位短整數。例如htonl表示將32位的長整數從主機位元組序轉換為網路位元組序,例如將IP地址轉換後準備傳送。如果主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回,如果主機是大端位元組序,這些函式不做轉換,將引數原封不動地返回

9.地址格式轉化

十進位制點分形式轉化為二進位制格式:inet_addr, inet_pton

(1)inet_addr()

函式的原型:unsigned long int inet_addr(const char *cp)

返回值:成功則返回對應的二進位制資料,失敗-1

函式的引數:cp:放置如“192.168.1.100”的點分IP地址

(2)inet_pton()

函式的原型:int inet_pton(int af,const char *src,void *dest)

函式的引數:af:AF_INET  AF_INET6

        src:點分的要轉化的IP地址

返回值:成功1,格式無效0 出錯-1

(3)inet_ntop

函式的作用:二進位制地址轉化成十進位制點分形式

函式的原型:const char * inet_ntop(int af,const void* src,socket_t size)

10.Linux UDP網路程式設計函式

(1)sendto

函式的作用:傳送socket資料,UDP使用較多

函式的原型:int sendto(int sockfd,void* msg,int len,unsigned int flags,const struct sockaddr * to,int tolen)

函式的引數:sockfd:套接字描述符

        msg:傳送的訊息記憶體

        len:訊息長度

        toaddr:要發訊息的目的地址

        tolen:sizeof(struct sockaddr)

返回值:成功:實際傳送的位元組數,出錯:-1

(2)recvfrom

函式的作用:從sockfd接受資料

函式的原型:int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr * fromaddr,int * fromlen)

返回值:成功:返回接收的位元組長度   出錯:-1

補充:

1.五類IP的範圍及應用

IP地址分為五類,A類保留給政府機構,B類分配給中等規模的公司,C類分配給任何需要的人,D類用於組播,E類用於實驗,各類可容納的地址數目不同。

其中A類、B類、和C類這三類地址用於TCP/IP節點,其它兩類D類和E類被用於特殊用途。

A類地址

⑴ A類地址第1位元組為網路地址,其它3個位元組為主機地址。

⑵ A類地址範圍:1.0.0.1—126.155.255.254

⑶ A類地址中的私有地址和保留地址:

① 10.X.X.X是私有地址(所謂的私有地址就是在網際網路上不使用,而被用在區域網絡中的地址)。

② 127.X.X.X是保留地址,用做迴圈測試用的。

B類地址

⑴ B類地址第1位元組和第2位元組為網路地址,其它2個位元組為主機地址。

⑵ B類地址範圍:128.0.0.1—191.255.255.254。

⑶ B類地址的私有地址和保留地址

① 172.16.0.0—172.31.255.255是私有地址

② 169.254.X.X是保留地址。如果你的IP地址是自動獲取IP地址,而你在網路上又沒有找到可用的DHCP伺服器。就會得到其中一個IP。

C類地址

⑴ C類地址第1位元組、第2位元組和第3個位元組為網路地址,第4個個位元組為主機地址。另外第1個位元組的前三位固定為110。

⑵ C類地址範圍:192.0.0.1—223.255.255.254。

⑶ C類地址中的私有地址:

192.168.X.X是私有地址。

D類地址

⑴ D類地址不分網路地址和主機地址,它的第1個位元組的前四位固定為1110。

⑵ D類地址範圍:224.0.0.1—239.255.255.254

E類地址

⑴ E類地址也不分網路地址和主機地址,它的第1個位元組的前五位固定為11110。

⑵ E類地址範圍:240.0.0.1—255.255.255.254

2.如何讓UDP實現可靠傳輸

自定義通訊協議,在應用層定義一些可靠的協議,比如檢測包的順序,重複包等問題,如果沒有收到對方的ACK,重新發包

UDP沒有Delievery Garuantee,也沒有順序保證,所以如果你要求你的資料傳送與接受既要高效,又要保證有序,收包確認等,你就需要在UDP協議上構建自己的協議。比如RTCP,RTP協議就是在UPD協議之上專門為H.323協議簇上的IP電話設計的一種介於傳輸層和應用層之間的協議。

3.三次握手、四次揮手詳細描述過程及作用、優缺點

(建立連線協議)三次握手的過程

(1) 客戶端傳送一個帶SYN標誌的TCP報文到伺服器,這是三次握手過程中的報文1

(2) 伺服器端迴應客戶端的,這是三次握手過程中的第2個報文,這個報文同時帶ACK標誌和SYN標誌。表示對剛才客戶端SYN報文的迴應,同時又標誌SYN給客戶端,詢問客戶端是否準備好進行資料通訊

(3) 客戶必須再次迴應服務端一個ACK報文,這是報文3。

三次握手的作用

檢測雙方的傳送和接受能力是否正常

三次握手的優點:

如果未收到客戶端的連線確認,伺服器就不會建立該連線。從而避免浪費伺服器的資源。

三次握手的缺點:

讓攻擊者有機可趁,通過TCP協議的缺陷,可以傳送大量的偽造源地址的攻擊報文,不迴應ACK包,伺服器預設重試五次,就可能造成目標伺服器中的佇列被佔滿,阻止其他合法使用者進行訪問。

(連線終止協議)四次揮手的過程

(1) TCP客戶端傳送一個FIN,用來關閉客戶到伺服器的資料傳送(報文段4)

(2) 伺服器收到這個FIN,他發回一個ACK,確認序號為收到的序號加1(報文段5),和SYN一樣,一個FIN將佔用一個序號

(3) 伺服器關閉客戶端的連線,傳送一個FIN給客戶端(報文段6)

(4) 客戶端發回ACK報文確認,並將確認序號設定為收到序號加1(報文段7)

四次揮手的作用

全雙工的工作模式下,需要雙方均關閉連線

4.TCP、UDP的選擇

使用TCP:

當對網路通訊質量有要求的時候,比如:整個資料要準確無誤的傳遞給對方,這往往用於一些要求可靠的應用,比如HTTP、HTTPS、FTP等傳輸檔案的協議,POP、SMTP等郵件傳輸的協議。

在日常生活中,常見使用TCP協議的應用如下:

瀏覽器,用的HTTP

FlashFXP,用的FTP

Outlook,用的POP、SMTP

Putty,用的Telnet、SSH

QQ檔案傳輸

…………

使用UDP:

當對網路通訊質量要求不高的時候,要求網路通訊速度能儘量的快,這時就可以使用UDP。

比如,日常生活中,常見使用UDP協議的應用如下:

QQ語音

QQ視訊

TFTP

……