TCP/IP總結

1、In Action

(1)TCP編程的服務器端一般步驟:

a、創建一個socket,用函數socket();

#include <sys/types/h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

b、設置socket屬性,用函數setsockopt();  (可選)

c、綁定IP地址、端口等信息到socket上,用函數bind();

int  bind(int sockfd, struct sockaddr * myaddr, int addrlen);

d、開啓監聽,用函數listen();

int listen(int sockfd, int backlog);將套接字設置爲監聽模式,以等待連接請求。

e、接收客戶端上來的連接,用函數accept();

int accept(int sockfd, struct sockaddr *addr, int *addrlen);接受連接請求,並返回一個與此次連接對應的套接字,此時addr爲客戶端的addr信息。

f、收發數據,用函數send()和recv(),或者read()和write();

int read(int fd, char * buf, int len);

int write(int fd, char * buf, int len);

用返回的套接字和客戶端進行通信。

g、關閉連接

int close(int sockfd);

關閉當前的連接,進入等待狀態,繼續等待客戶端的連接;

關閉服務器端的套接字描述符。

h、關閉監聽

 

(2)TCP編程的客戶端一般步驟:

a、創建一個socket,用函數socket();

b、設置socket屬性,用函數setsockopt();  (可選)

c、綁定IP地址、端口等信息到socket上,用函數bind();(可選)

d、設置要連接的對方的IP地址和端口等屬性;

e、連接服務器,用函數connect();

int connect(int sockfd, struct sockaddr * servaddr, int addrlen);其中參數servaddr指定遠程服務器的套接字地址,包括服務器的IP地址和端口號。

f、收發數據,用函數send()和recv(),或者read()和write();

g、關閉網絡連接

 

(3)UDP編程的服務器端一般步驟:

a、創建一個socket,用函數socket();

b、設置socket屬性,用函數setsockopt();  (可選)

c、綁定IP地址、端口等信息到socket上,用函數bind();

d、循環接收數據,用函數recvfrom();

e、關閉網絡連接

 

(4)UDP編程的客戶端一般步驟:

a、創建一個socket,用函數socket();

b、設置socket屬性,用函數setsockopt();  (可選)

c、綁定IP地址、端口等信息到socket上,用函數bind(); (可選)

d、設置對方的IP地址和端口等屬性;

e、發送數據,用函數sendto();

f、關閉網絡連接

 

2、TIPS

(1)TCP的可靠保證,是它在傳輸前採用三次握手雙向機制建立連接,這保證校驗了數據,保證了它的可靠性。而UDP的反應速度更快。

UDP是不可靠的傳輸協議,即發出去的數據不一定接收得到。

 

(2)TCP/IP協議組流行,是因爲它可以用在各種各樣的信道和底層協議之上。如:T1和X.25、以太網以及RS-232串行接口。TCP/IP協議是一組包括TCP協議、IP協議、UDP協議、ICMP協議和其他一些協議的協議組。

 

傳統的開放式系統互連參考模型,是一種通信協議的7層抽象的參考模型,其中每一層執行某一特定任務。該模型的目的是使各種硬件在相同的層次上相互通信

7層是:物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層、應用層。

 

TCP/IP通訊協議採用了4層的層級結構,每一層都通過它的下一層所提供的網絡來完成自己的需求。這4層爲:

應用層:應用程序間溝通的層,如SMTP、FTP、Telnet(網絡遠程訪問協議);

傳輸層:在此層中,它提供了節點間的數據傳送服務。TCP和UDP給數據包加入傳輸數據並把它傳輸到下一層中。這一層負責傳送數據,且確定數據已被送達並接收

網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都能到達目的主機,但不檢查是否被正確接收。

網絡接口層:對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、Serial Line等)來傳送數據。

 

(3)IP

IP層接收由更低層(網絡接口層,如以太網設備驅動程序)發來的數據包,並把該數據包發送到更高層;IP層也能把從TCP或UDP層接收來的數據包傳送到更底層。

IP數據包是不可靠的,因爲IP沒有做任何事情來確認數據包是按順序發送的或者沒有被破壞。

IP數據包中含有發送它的主機地址(源地址)和接收它的主機地址(目的地址)。

 

(4)TCP

若IP數據包中有已經封裝好的TCP數據包,則IP將把它們向上傳送到TCP層。TCP將包排序並進行錯誤檢查,同時實現虛電路間的連接TCP數據包中包括序號和確認,所以未按照順序收到的包可以被排序,而損壞的包可以被重傳

 

面向連接的服務(如FTP、Telnet、SMTP等)需要高度的可靠性,所以它們使用了TCP。

 

(5)UDP

UDP主要用於面向查詢——應答的服務,如NFS,不被應用於使用虛電路的面向連接的服務。

欺騙UDP包比欺騙TCP包更容易,因爲UDP沒有建立初始化連接(也可以稱爲握手),因爲在兩個系統間沒有虛電路。 

 

(6)ICMP

和IP位於同一層,被用來傳送IP的控制信息,主要用來提供有關通向目的地址的路徑信息。ICMP的redirect信息通知主機通向其它系統的更準確的路徑,unreachable信息則指出路徑有問題。ping是基於ICMP的服務。

 

(7)

TCP和UDP服務通常有一個c/s的關係。如一個Telnet服務進程開始在系統上處於空閒狀態,等待着連接。

兩個系統間的多重Telnet連接是如何相互確認並協調一致?——>TCP或UDP連接唯一地使用每個信息中的如下四項進行確認:

a、源IP地址

b、目的IP地址

c、源端口

d、目的端口

端口是一個軟件結構,被客戶程序或服務進程用來發送和接收信息。一個端口對應一個16bit的數

 

3、PS

(1)TCP協議如何關閉連接:

由於TCP連接是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的數據發送任務後就能發送一個FIN來終止這個方向的連接。收到一個FIN只意味着這一方向上沒有數據流動,一個TCP連接在收到一個FIN後仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

a、首先,c(client)調用close(),給server(s)發送FIN,請求關閉連接;s收到FIN之後給c發送ACK,同時關閉讀通道,s狀態變爲CLOSE_WAIT狀態。

b、c收到對自己FIN確認的ACK之後,關閉寫通道;

c、然後s調用close()關閉連接,給c發送FIN,c收到後給s發送ACK,同時c關閉讀通道,進入TIME_WAIT狀態;

d、s收到c的ACK之後,關閉寫通道,TCP連接轉爲CLOSED狀態,也就是關閉連接。

e、c在TIME_WAIT狀態下要等待最大數據段生存期的兩倍,然後才進入CLOSED狀態,TCP關閉連接的過程才徹底結束。

一個FIN佔用一個序號。 

 

(2)TCP協議提供可靠的連接服務,採用三次握手建立一個連接。

a、第一此握手:建立連接時,客戶端A發送SYN包(SYN=j)到服務器B,並進入SYN_SEND狀態,等待服務器B確認;

b、第二次握手:服務器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時服務器B進入SYN_RECV狀態;

c、第三次握手:客戶端A收到服務器B的SYN+ACK包,向服務器B發送確認包ACK(ACK=k+1),此包發送完畢,客戶端A和服務器B進入ESTABLISHED狀態,完成三次握手。

完成三次握手,客戶端與服務器開始傳送數據。

 

(3)爲什麼建立連接協議是三次握手,而關閉連接是四次揮手?

因爲服務器端的Listen狀態下的socket,當收到SYN報文的建連接請求後,可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的

 

(4)爲什麼TIME_WAIT狀態還需要等2MSL後才能返回到closed狀態?

因爲雖然雙方都同意關閉連接了,且握手的4個報文也都協調和發送完畢,按理可以直接回到closed狀態(就好比從SYN_SEND狀態到ESTABLISH狀態那樣);但因爲我們必須要假想網絡是不可靠的,你無法保證你最後發送的ACK報文會一定被對方收到,因此對方處於LAST_ACK狀態下的socket可能會因爲超時未收到ACK報文,而重發FIN報文,所以這個TIME_WAIT狀態的作用就是用來重發可能丟失的ACK報文

 

(5)FIN_WAIT_1:

 FIN_WAIT_1和FIN_WAIT_2狀態都是表示等待對方的FIN報文。FIN_WAIT_1狀態實際上是當socket在established狀態時,它想主動關閉連接,向對方發送了FIN報文,此時該socket即進入到FIN_WAIT_1狀態。而當對方迴應ACK報文後,則進入到FIN_WAIT_2狀態。

 

(6)TIME_WAIT:表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到closed可用狀態了。若FIN_WAIT_1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。

 

(7)CLOSING:

實際情況下很少見。正常情況下,當你發送FIN報文後,按理說應該先收到(或同時收到)對方的ACK報文,再收到對方的FIN報文。但是CLOSING狀態表示你發送FIN報文後,並沒有收到對方的ACK報文,反而卻收到了對方的FIN報文。什麼情況下會出現此情況呢?——>若雙方幾乎在同時close一個socket,那麼就出現了雙方同時發送FIN報文的情況,即會出現CLOSING狀態,表示雙方都正在關閉socket連接。

 

(8)CLOSE_WAIT

表示在等待關閉。當對方close一個socket 後發送FIN報文給自己,你會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來,你是否還有數據發送給對方,若沒有,你就可以close這個socket,發送FIN報文給對方,即關閉連接。因此在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連接。

 

(9)LAST_ACK

它是被動關閉一方在發送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章