计算机网络基本知识
计算机网络基本概念
https://www.cnblogs.com/xdyixia/p/9275246.html
补充:
应用层:允许访问OSI环境的手段(应用协议数据单元APDU)——报文:应用进程通过端口送到传输层的数据单元,典型的报文包含一个传输层首部和应用程序数据。报文包含了将要发送的完整的数据信息,其长短不需一致。
表示层:对数据进行翻译、加密和压缩(表示协议数据单元PPDU)
会话层:建立、管理和终止会话(会话协议数据单元SPDU)
传输层:提供端到端的可靠报文传递和错误恢复(段Segment)——报文段:用户进程送下来的数据加上TCP或者UDP头后的数据报
网络层:负责数据包从源到宿的传递和网际互连(包PackeT)——分组/包:即包括传输层送下来的完整的不需要分片的数据报,也包括由于报文大于网络接口的MTU而进行的分片。
数据链路层:将比特组装成帧和点到点的传递(帧Frame)——
物理层:通过媒介传输比特,确定机械及电气规范(比特Bit)——
帧(frame):数据链路层的协议数据单元,它包括三部分:帧头、数据部分、帧尾。其中,帧头和帧尾包含一些必要的控制信息,比如同步信息、地址信息、差错控制信息等。
数据包(packet):在TCP/IP协议通信传输中的数据单元,也称为“包”。指自包含的,带有足够寻址信息,可独立地从源主机传输到目的主机,而不需要以来早期地源主机和目的主机之间交换信息以及传输网络地数据包。
报文(message):是网路中交换与传输的数据单元,也是网络传输的单元,报文包含了将要发送的完整的数据信息,其长短不一。报文在传输过程中会不断地封装成分组、包、帧来传输,封装的方式就是添加一些控制信息组成的部首,那些就是报文头。
echo客户端和服务器
实现的基本功能:
客户端:在和服务器建立连接后,客户端进入循环反复从标准输入读取文本行,发送文本行给服务器 ,从服务器读取回送的行,并输出结果到标准输出,直到循环终止。
服务器:再打开侦听描述符后,循环等待来自客户端的连接请求,输出已连接客户端的域名和IP地址,并调用echo函数为客户端服务。在echo程序返回后主动关闭已连接描述符。
file echoclient.c:
1 /**客户端主程序**/ 2 #include "csapp.h"//需自己定义的头文件 3 int main(int argc, char **argv)//运行时,把命令行参数传入主程序。argc--命令行参数总个数,包括可执行程序名;argv[i]--第 i 个参数;argv[0]--可执行程序名。 4 { 5 int clientfd;//clientfd--套接字描述符; 6 char *host, *port, buf[MAXLINE];//host--服务器主机IP地址;port-服务器端口号;buf--缓存; 7 rio_t rio;//缓存形式 8 9 if (argc != 3) 10 { 11 fprintf(stderr, "usage: %s \n", argv[0]);//将错误提示输入到stderr定向的设备,如显示器,文件,打印机 12 exit(0); 13 } 14 host = argv[1]; 15 port = argv[2]; 16 17 clientfd = Open_clientfd(host, port);//建立与服务器host的连接,返回给客户端一个打开的套接字描述符,可以进行读写与服务器进行通信 18 Rio_readinitb(&rio, clientfd); //rio_t 结构体初始化,将描述符clientfd与一个缓冲区绑定 19 20 while (Fgets(buf, MAXLINE, stdin) != NULL)//Fgets从标准输入读取文本行到buf 21 { 22 //发送文本行给服务器 23 Rio_writen(clientfd, buf, strlen(buf)); //将buf中传送最多strlen(buf)个字节到描述符clientfd中。如果成功,返回写入的字节数,如果出错返回-1. 24 //从服务器读取回送的行 25 Rio_readlineb(&rio, buf, MAXLINE);//从rio读入一个文本行数据复制到内存位置buf 26 //输出结果到标准输出 27 Fputs(buf, stdout);//把字符串buf写入到指定的流 stdout中,但不包括空字符。 28 } 29 Close(clientfd);//关闭描述符 30 exit(0);//正常退出 31 }
file echoserver.c:
1 /**迭代echo服务器主程序**/ 2 #include "csapp.h" 3 int main(int argc, char **argv) 4 { 5 int listenfd, connfd;//listenfd--侦听描述符;connfd--已连接描述符;port--侦听端口号; 6 socklen_t clientlen; 7 struct sockaddr_storage clientaddr;//套接字地址结构sockaddr_storage足够大 8 char client_hostname[MAXLINE], client_port[MAXLINE]; 9 10 if (argc != 2) 11 { 12 fprintf(stderr, "usage: %s \n", argv[0]); 13 exit(0); 14 } 15 16 listenfd = Open_listenfd(argv[1]);//服务器创建侦听描述符,侦听服务器的端口argv[1] 17 while (1) 18 { 19 clientlen = sizeof(struct sockaddr_storage); 20 //等待来自客户端的请求 21 connfd = accept(listenfd, (SA *)&clientaddr, &clientlen);//等待来自客户端的请求,返回前在clientaddr中填上客户端的套接字地址 22 23 //将套接字的地址结构转clientaddr换为主机和服务名字符串client_hostname和client_port 24 Getnameinfo((SA *)&clientaddr, clientlen, client_hostname, MAXLINE, 25 client_port, MAXLINE, 0); 26 printf("server connected to (%s,%s)\n", client_hostname, client_port); 27 28 //调用echo为客户端服务 29 echo(connfd); 30 Close(connfd); 31 } 32 exit(0); 33 }
file echo.c:
1 /**读和回送文本行**/ 2 #include "csapp.h" 3 void echo(int connfd) //connfd--已连接描述符; 4 { 5 size_t n; 6 char buf[MAXLINE]; 7 rio_t rio; 8 9 Rio_readinitb(&rio, connfd);//rio_t 结构体初始化,将缓冲区与文件描述符connfd绑定 10 while ((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0)//从文件rio读取下一行到内存buf,一行最大长度为MAXLINE。直到遇到EOF; 11 { //line:netp:echo:eof 12 printf("server received %d bytes\n", n); 13 Rio_writen(connfd, buf, n);//将buf中传送最多strlen(buf)个字节到描述符connfd中。rio_writen不需要写缓冲,故直接使用int型描述符connfd。 14 } 15 }
补充:
"csapp.h"文件: https://blog.csdn.net/zhongshijunacm/article/details/53506892
linux RIO包 :https://blog.csdn.net/u013613341/article/details/51019075
参考:《深入理解计算机系统》