目錄
一、TCP基本概念
二、ser服務器代碼
三、cil客戶端代碼?
四、面試常問問題
4.1?TCP的可靠性怎么保證或怎么實現?
4.2 具體說一下滑動窗口
一、TCP基本概念
TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層協議。以下是TCP的一些基本概念:
-
面向連接:在數據傳輸之前,TCP在發送方和接收方之間建立一個連接。數據傳輸完成后,連接被釋放。
-
可靠性:TCP提供可靠的數據傳輸,確保數據按照正確的順序到達目的地,并且可以檢測和糾正傳輸過程中出現的錯誤。
-
流控制:TCP使用滑動窗口協議進行流量控制,以確保發送端和接收端之間的數據傳輸速率合理,不會發生數據丟失或超負荷的情況。
-
擁塞控制:TCP通過控制數據包的發送速率來避免網絡擁塞,以確保網絡的穩定性和流暢性。
-
分段和重組:TCP在傳輸數據時會將數據分成較小的數據段進行傳輸,接收方收到數據后會重新組裝成完整的數據。
-
端到端通信:TCP是端到端通信協議,意味著通信雙方直接進行數據傳輸,而不需要經過中間設備的處理。
服務端:
1. socket():創建一個新的套接字。
2. bind(ip+port):將套接字綁定到指定的IP地址和端口號上,以便監聽來自該地址和端口的連接請求。
3. listen():使套接字進入監聽狀態,等待客戶端的連接請求。
4. accept():接受客戶端的連接請求,建立連接。
5. recv():接收來自客戶端的數據。
6. send():向客戶端發送數據。
7. close():關閉套接字,結束通信。客戶端:
1. socket():創建一個新的套接字。
2. connect(ip+port):向服務端的指定IP地址和端口號發起連接請求。
3. send():向服務端發送數據。
4. recv():接收來自服務端的數據。
5. close():關閉套接字,結束通信。
TCP編程流程:
1.TCP服務器端編程流程:socket創建套接字->bind綁定IP和端口->listen創建監聽隊列->accept接受連接->receive接收數據->send發送數據->close關閉連接。
2.TCP客戶端編程流程:socket創建套接字->connect發起連接->send發送數據->receive接收數據->close關閉連接。
二、ser服務器代碼
TCP服務器程序,用于接受客戶端的連接請求,并與客戶端進行數據交換 。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int main()
{//創建套接字(打開文件,文件描述符) 套接字可以通過網絡收發數據int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){exit(1);}struct sockaddr_in saddr,caddr;//服務器的ip端口memset(&saddr,0,sizeof(saddr));//清空saddr.sin_family=AF_INET;//填充saddr.sin_port=htons(6000);//制定端口號為6000 小于1024是知名端口,1024~4096是保留的端口,4096以上是臨時端口saddr.sin_addr.s_addr=inet_addr("127.0.0.1");//指定ip+端口int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//綁定,指定應用程序使用的ip及端口if(res==-1){printf("bind err\n");exit(1);}res=listen(sockfd,5);if(res==-1){exit(1);}while(1){int len=sizeof(caddr);//accept接受連接,如果沒人連接,則阻塞int c=accept(sockfd,(struct sockaddr*)&caddr,&len);if(c<0){break;}printf("accept c=%d\n",c);pid_t pid=fork();if(pid==0){while(1){char buff[128]={0};int n=recv(c,buff,127,0);//接受連接,接收數據,會阻塞,也可以換成read()if(n<=0){break;}printf("recv:%s\n",buff);send(c,"ok",2,0);//發送數據,也可以換成write()}printf("client close\n");close(c);exit(0);}close(c);}
}
導入頭文件:程序中導入了一些標準的頭文件,包括stdio.h、stdlib.h、unistd.h、string.h、sys/socket.h、netinet/in.h、arpa/inet.h。
創建套接字:使用socket函數創建一個套接字,同樣指定協議族(AF_INET,表示IPv4)、套接字類型(SOCK_STREAM,表示TCP流套接字)和協議參數(0)。
設置服務器地址:定義了兩個結構體變量saddr和caddr,分別表示服務器和客戶端地址。初始化saddr,并指定服務器的IP地址為"127.0.0.1",端口號為6000。
綁定地址:使用bind函數將套接字和服務器地址綁定在一起,指定服務器應用程序使用的IP地址和端口號。
監聽連接:使用listen函數監聽連接請求,指定最大連接數為5。
接受連接:通過accept函數接受客戶端的連接請求。如果有客戶端連接,則創建一個新的套接字描述符c,并接受連接。
多進程處理:在子進程中處理客戶端的數據通信。在處理數據的循環中,接收客戶端發送的數據,如果接收到數據則打印并發送"ok"回復客戶端。如果接收到的數據長度小于等于0,表示客戶端關閉連接,則跳出處理數據的循環,關閉客戶端的套接字描述符c。
多進程處理:在父進程中關閉已接受的客戶端連接。
三、cil客戶端代碼?
客戶端程序,用于連接到服務器并進行數據交換。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int main()
{//創建套接字int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd==-1){exit(1);}struct sockaddr_in saddr;//指定服務器的ip和端口portmemset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(6000);//htons 轉為網絡字節序列 大端saddr.sin_addr.s_addr=inet_addr("127.0.0.1");int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res==-1){printf("connect err\n");exit(1);}char buff[128]={0};printf("input:\n");fgets(buff,128,stdin);send(sockfd,buff,strlen(buff)-1,0);//可以用writememset(buff,0,sizeof(buff));recv(sockfd,buff,127,0);printf("buff=%s\n",buff);close(sockfd);exit(0);
}
導入頭文件:程序中導入了一些標準的頭文件,包括stdio.h、stdlib.h、unistd.h、string.h、sys/socket.h、netinet/in.h、arpa/inet.h。
創建套接字:使用socket函數創建一個套接字,同樣指定協議族(AF_INET,表示IPv4)、套接字類型(SOCK_STREAM,表示TCP流套接字)和協議參數(0)。
設置服務器地址:定義了一個結構體變量saddr,表示服務器地址。初始化saddr,并指定服務器的IP地址為"127.0.0.1",端口號為6000。
連接服務器:使用connect函數連接服務器,將套接字和服務器地址綁定在一起,連接到指定的服務器IP和端口。
發送和接收數據:提示用戶輸入數據,通過fgets函數讀取用戶輸入的數據到緩沖區buff中。然后使用send函數將數據發送給服務器,發送的數據長度為輸入長度減去換行符。接收服務器返回的數據,使用recv函數將數據讀取到buff中。
打印數據:將接收到的數據打印輸出。
關閉連接:使用close函數關閉套接字,結束客戶端程序。
運行結果:
四、面試常問問題
4.1?TCP的可靠性怎么保證或怎么實現?
答:1.應答確認,超時重傳。
? ? ? ? 2.亂序重拍,去重。
? ? ? ? 3.滑動窗口,流量控制。
4.2 具體說一下滑動窗口
????????TCP (Transmission Control Protocol) 中的滑動窗口是一種流量控制和可靠傳輸的機制。它允許發送方在發送數據時一次傳輸多個數據包而不需要等待確認,從而提高了網絡的效率。滑動窗口的大小取決于接收方和發送方之間的協商,受限于網絡帶寬、延遲等因素。
????????在 TCP 的滑動窗口中,接收方會發送一個窗口大小的值給發送方,表示能夠接收的數據量。發送方根據這個窗口大小來控制發送的數據量,確保不會超出接收方的處理能力。一旦發送方發送了窗口大小的數據之后,就需要等待接收方發送確認信息(ACK)才能發送下一批數據。
????????通過滑動窗口機制,TCP 實現了可靠的數據傳輸。如果發送方未收到接收方的確認信息,發送方會重新發送相應的數據,直到接收方正確接收。這樣可以保證數據傳輸的正確性和完整性。
????????總的來說,TCP 中的滑動窗口對于保證數據的可靠傳輸起著至關重要的作用,通過有效地控制數據流量和協商窗口大小,可以提高網絡的吞吐量和傳輸效率。