1. 程式人生 > >TCP/IP協議學習總結

TCP/IP協議學習總結

本文為自己的學習總結,沒有那些大神們那麼的深入,只為自己的一些心得總結,有很多不足之處,請各位勿噴,望多多指正!!無限感激

一、TCP/IP協議

為什麼會有這個協議: 為了實現不同計算機系統/網路系統之間的通訊其他還有很多網路協議,只是很多隻能特定某些計算機系統間的通訊,通用性不強 TCP/IP協議是什麼: IP協議: 實現不同網路的互聯; TCP: 用於傳輸控制協議 TCP/IP協議的體系結構: 主要有四個層次:應用層(我們的資料)、傳輸層(TCP/UDP,實現傳輸資料)、網路層(IP層,實現不同網路之間的連結,包括如何                                       找到目標機器)、網路介面和物理層(實現真正的資料傳送)。 接下來深入理解這幾個協議:        實現網路互聯的協議(IP協議): 最主要的就是通過IP地址找到目標機器。IP地址有四類(A、B、C、D)                                                      A類:  1.0.0.1 ~ 127.255.255.255                                                      B類:  128.0.0.1 ~ 191.255.55.255                                                      C類:  192.0.0.1 ~ 223.255.255.255                                                      D類:  224.0.0.1~ 239.255.255.255 (用於組播)       實現資料傳播的協議:              TCP協議(傳輸控制協議): 必須先建立連線然後才能通訊(相當於打電話,必須得到應答只有才能通訊,而且有資料檢驗),可靠性高。              UDP協議(資料報文傳輸協議): 不可靠無連線傳輸(只管傳送出去,相當於寫信,對方收不收到都不管),傳輸快,但是不可靠常用於廣播 。 二、如何進行網路程式設計(Linux) Socket:程序通訊介面、網路通訊程式設計介面,不僅適用於本地程序的通訊, 還適用於網路之間程序的通訊。           面向連線的 Socket機制與國家電話網路有點類似:兩個電話號碼相當於兩個程序Socket號。電話的區號相當於一個網路地址,區內的一個單位交換機相當於一臺電腦主機,區內的每一個電話(號碼)相當於程序的Socket號。使用者打電話通訊前都需要有一個號碼,也就是兩個程序通訊前要有一個Socket號。撥打電話的時候相當於通過Socket號進行連線,如果對方不在用一個區域那麼就得加上區號也相當於網路地址(IP地址)。若果對方電話機存在並且空閒,那麼就進行通訊,想電話機發出資訊或者接收資訊,就相當於像Socket發出資訊或者接收資訊。我們在通過電話通訊的時候,電話機是遮蔽了整個電話系統裡面的東西(比如怎麼進行組網呀,怎麼進行查詢某個電話機呀等等),而Socket也是遮蔽了整個網際網路的細節(比如如何查詢到某個主機,如何建立連線等等),這樣的話,給應用層程式設計帶來了很多的方便之處。 Socket程式設計的注意事項: IP地址的繫結、埠號的繫結、位元組序(網路位元組序為大端序)、防火牆、超時等問題 Socket有三種類型,分別用於不同的協議:               流式套接字(SOCK_STREAM): 適用於 TCP協議             資料報套接字(SOCK_DGRAM): 適用於UDP協議             原始套接字(SOCK_RAM): 可以直接訪問 IP、ICMP層 網路程式設計常用介面函式: socket(): 建立套接字 bind(): 繫結本機地址和埠 connect(): 建立連線(用於TCP客戶端) listen(): 監聽套接字 accept(): 接受TCP連線(用於TCP伺服器) recv()、read()、recvfrom() : 接收資料,其中recvfrome()用於UDP協議 send()、write()、sendto(): 傳送資料,其中 sendto() 用於UDP協議 close()、shutdown() : 關閉套接字 常用結構體: struct sockaddr        //通用地址結構體 {     u_short sa_family;  //地址簇, AF_xxx
    char sa_data[14];  //十四位元組協議地址 } struct sockaddr_in      // Internet 協議地址結構體 {     u_short sin_family;    // 地址簇, AF_xxx     u_short sin_port;      //埠     struct in_addr sin_addr;  //IPV4地址     char sin_zero[8]; } 程式設計的總體思想是:尋找目標主機、尋找目標程序、通訊
TCP程式設計流程:  
例子: 伺服器端 #include "head_net.h" int main(int argc,char **argv) {     int sock_fd,conn_fd;     struct sockaddr_in sin,cin;     socklen_t len;     char cli_ip[16];     char buf[SIZE];     int ret;     if(argc != 2){ fprintf(stderr,"Usage %s <SRV_IP>\n",argv[0]); exit(1);     }     /*1:建立socket*/     if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0)       p_error("socket");     /*2:繫結地址*/     bzero(&sin,sizeof(sin));     sin.sin_family = AF_INET;     sin.sin_port = htons(PORT);     sin.sin_addr.s_addr = inet_addr(SRV_IP);     if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) < 0) p_error("bind");     /*3:監聽*/     if(listen(sock_fd,N) < 0) p_error("listen");     /*4:連線,三次握手*/     if( (conn_fd = accept(sock_fd,(struct sockaddr*)&cin,&len))<0) p_error("accept");     /*5:通訊*/     while(1){ bzero(buf,SIZE); if( (ret = read(conn_fd,buf,SIZE)) < 0)     p_error("read"); else if(0 == ret){     close(sock_fd);     break; } if(strncmp(buf,"quit",4) == 0)     break; printf("%s",,buf);     }         /*6:關閉socket*/     shutdown(conn_fd,0);     return 0; } 客戶端: #include "head_net.h" int main(int argc,char **argv) {     int sock_fd;     struct sockaddr_in sin;     char buf[SIZE];     if(argc != 2){ fprintf(stderr,"Udage %s <des_ip>\n",argv[0]); exit(1);     }     if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) p_error("socket");     bzero(&sin,sizeof(sin));     sin.sin_family = AF_INET;     sin.sin_port = htons(PORT);     sin.sin_addr.s_addr = inet_addr(argv[1]);     while(1){ bzero(buf,SIZE); fgets(buf,SIZE,stdin); buf[strlen(buf)-1] = '\0'; sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin)); if(strncmp(buf,"quit",4)! == 0)     break;     }     close(sock_fd);     return 0; } UDP程式設計流程:

例子: 伺服器 #include "head_net.h" int main(int argc,char **argv) {     int sock_fd;     struct sockaddr_in sin,cin;     char buf[SIZE];     char cli_ip[16];     socklen_t len;     if(argc != 2){ fprintf(stderr,"Udage %s <des_ip>\n",argv[0]); exit(1);     }     if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) p_error("socket");     bzero(&sin,sizeof(sin));     sin.sin_family = AF_INET;     sin.sin_port = htons(PORT);     sin.sin_addr.s_addr = inet_addr(argv[1]);     if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) < 0) p_error("bind");     len = sizeof(cin);     while(1){ bzero(buf,SIZE); recvfrom(sock_fd,buf,SIZE,0,(struct sockaddr*)&cin,&len); if(strncmp(buf,"quit",4) == 0)     break; strcpy(cli_ip,inet_ntoa(cin.sin_addr)); printf("%s from %s\n",buf,cli_ip);     }     close(sock_fd);     return 0; } 客戶端: #include "head_net.h" int main(int argc,char **argv) {     int sock_fd;     struct sockaddr_in sin;     char buf[SIZE];     if(argc != 2){ fprintf(stderr,"Udage %s <des_ip>\n",argv[0]); exit(1);     }     if( (sock_fd = socket(AF_INET,SOCK_DGRAM,0)) < 0) p_error("socket");     bzero(&sin,sizeof(sin));     sin.sin_family = AF_INET;     sin.sin_port = htons(PORT);     sin.sin_addr.s_addr = inet_addr(argv[1]);     while(1){ bzero(buf,SIZE); fgets(buf,SIZE,stdin); buf[strlen(buf)-1] = '\0'; sendto(sock_fd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin)); if(strncmp(buf,"quit",4)! == 0)     break;     }     close(sock_fd);     return 0; }