作者:手机用户2502939003 | 来源:互联网 | 2023-05-18 16:16
一、网络通信网络是通过物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的,通过信息交换实现人与人、人与计算机、计算机与计算机之间的通信。1.网络通信要遵守网络协议
一、网络通信
网络是通过物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的,通过信息交换实现人与人、人与计算机、计算机与计算机之间的通信。
1. 网络通信要遵守网络协议,局域网中最常用的有三个网络协议:MICROSOFT的NETBEUI、NOVELL的IPX/SPX和TCP/IP协议。
a> NetBEUI - 网络基本输入输出系统扩展用户接口。NETBEUI是为IBM开发的非路由协议,用于携带NETBIOS通信。NETBEUI缺乏路由和网络层寻址功能,既是其最大的优点,也是其最大的缺点。
b> IPX/SPX - 互连网包交换/顺序包交换。IPX是NOVELL用于NETWARE客户端/服务器的协议群组,具有完全的路由能力,但是可扩展性受到其高层广播通信和高开销的限制。
c> TCP/IP允许与Internet完全的连接,这是其它协议不具备的。同时具备了可扩展性和可靠性的需求,但是不牺牲了速度和效率。
二、TCP/IP协议
1. 参考模型
国际标准化组织(ISO)定义了网络协议的基本框架,被称为OSI模型。OSI模型包括应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。这个7层的协议模型虽然规定得非常细致和完善,但在实际中却得不到广泛的应用,其重要的原因之一就在于它过于复杂,但它仍是此后很多协议模型的基础。与此相区别的TCP/IP协议模型将OSI的7层协议模型简化为4层,从而更有利于实现和使用。TCP/IP协议模型包括应用层、传输层、网络层、网络接口层。
2. TCP/IP协议的4层协议
TCP/IP协议是网络中使用的基本通信协议。
网络接口层:网络接口层是TCP/IP的最底层,负责将二进制流转换成数据帧,并进行数据帧的发送和接收。数据帧是网络传输的基本单元。
网络层:网络层负责在主机之间的通信中选择数据包的传输路径,即 路由。当网络收到传输层的请求后,使用路由算法来确定是直接交付数据包,还是把它传递给路由器,最后把数据包交给适当的网络接口进行传输。
传输层:负责实现应用程序之间的通信服务,又称为端到端通信,传输层要提供可靠的传输服务,以确保数据到达无差错、无乱序。为了达到这个目的,传输层协议软件要进行协商。传输层协议软件要把传输的数据流分为分组。
应用层:应用层是分层模型的最高层。应用程序使用相应的应用层协议,把封装好的数据交给传输层或是传输层接收数据并处理。
3. 分层模型图
4. TCP与UDP的概念
TCP(传输控制协议):为应用程序提供可靠的通信连接,适合一次传输大批数据的情况,并适应要求得到相应的应用程序。
UDP(用户数据包协议):提供无连接通信,且不对传送包进行可靠的保证,适合一次传输少量数据。
三、TCP协议
TCP是TCP/IP体系中面向连接的传输层协议,提供全双工和可靠交付的服务,采用许多机制来确保数据的可靠性。
首先,TCP为发送的数据加上序列号,来保证数据能被接收方接收,且只能被正确接收一次。其次,TCP采用具有重传功能的确认技术作为可靠数据流传输服务的基础。由于发送方接收到数据之后会返回一个ACK信号,所以发送方检测ACK信号来判断是否接收成功。如果接收失败,就会重新发送刚才的数据。最后,TCP采用可变长的滑动窗口协议进行流量控制,防止发送方与接收方数据不匹配造成数据丢失。采用可变长的滑动窗口,可以对接收/发送的数据进行动态调节,灵活性更强。
四、UDP协议
UDP也是TCP/IP体系中面向连接的传输层协议,是一种无连接协议,因此不需要三次握手来建立连接。UDP协议比TCP协议更为高效,解决了实时性的问题。
五、TCP例题
(1)TCP服务器
[html] view plain copy
- <span style="font-size:14px;">#include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
-
- #define MAX_SIZE 512
- #define PORT 3332 //端口号
-
- int main()
- {
- int sockfd;
- int sock_fd;
- int recvnum;
- int addrlen = sizeof(struct sockaddr);
-
- struct sockaddr_in my_addr;
- struct sockaddr addr;
-
- char buf[MAX_SIZE];
-
- // 填充服务器端的资料,用于套接字绑定
- bzero(&my_addr,sizeof(struct sockaddr_in));
-
- my_addr.sin_family = AF_INET; //设置为IPV4
- my_addr.sin_port = htons(PORT); //将端口号主机序转换为网络序
- my_addr.sin_addr.s_addr = inet_addr("192.168.1.132"); //IP设置为192.168.1.132
-
- //创建套接字,TCP/IPV4
- sockfd = socket(AF_INET,SOCK_STREAM,0);
- if(sockfd < 0)
- {
- printf("create socket error!\n");
- exit(1);
- }
-
- //绑定套接字
- if(bind(sockfd,(struct sockaddr*)&my_addr,addrlen) < 0)
- {
- printf("bind error\n!");
- exit(1);
- }
-
- //监听端口和IP,允许客户端最大数目为3
- if(listen(sockfd,3) < 0)
- {
- printf("listen error!\n");
- exit(1);
- }
-
- //建立服务器和客户端连接
- sock_fd = accept(sockfd,&addr,&addrlen);//建立连接后产生新的套接字描述符
-
- if(sock_fd < 0)
- {
- printf("accept error!\n");
- exit(1);
- }
-
- //接收数据
- if((recvnum = recv(sock_fd,(void *)buf,MAX_SIZE,0)) < 0)
- {
- printf("recv error!\n");
- exit(1);
- }
-
- buf[recvnum]='\0';
- printf("recv from client: %s\n",buf);
-
- memset(buf,0,MAX_SIZE);
-
- //关闭连接
- close(sock_fd);
- close(sockfd);
-
- return 0;
- }
- span>
(2)TCP客户端[html] view plain copy
- <span style="font-size:14px;">#include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <arpa/inet.h>
-
- #define MAX_SIZE 512
- #define PORT 3332 //端口号
-
- int main()
- {
- int sockfd;
- int addrlen = sizeof(struct sockaddr);
-
- char buf[MAX_SIZE];
-
- struct sockaddr_in serv_addr;
-
- //填充服务器端资料
- bzero(&serv_addr,sizeof(struct sockaddr_in));
-
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = ntohs(PORT);
- serv_addr.sin_addr.s_addr = inet_addr("192.168.1.132");
-
- //创建套接字,IPV4/TCP
- sockfd = socket(AF_INET,SOCK_STREAM,0);
- if(sockfd < 0)
- {
- printf("create socket error!\n");
- exit(1);
- }
-
- //连接服务器
- if(connect(sockfd,(struct sockaddr *)&serv_addr,addrlen) < 0)
- {
- printf("connect error !\n");
- exit(1);
- }
-
- memset(buf,0,MAX_SIZE);
- printf("enter some text:");
- scanf("%s",buf);
-
- //发送数据到服务器
- if(send(sockfd,(void *)buf,MAX_SIZE,0) < 0)
- {
- printf("send error!\n");
- exit(1);
- }
-
- //关闭连接
- close(sockfd);
-
- return 0;
- }
- span>
六、UDP例题
(1)UDP服务器
[html] view plain copy
- <span style="font-size:14px;">#include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
-
- #define PORT 3212
- #define MAX_SIZE 512
-
- int main()
- {
- int sockfd;
- int len = sizeof(struct sockaddr);
-
- char buf[MAX_SIZE];
- char buffer[MAX_SIZE];
-
- struct sockaddr_in serv_addr;
-
- //创建套接字,IPV4/UDP
- sockfd = socket(AF_INET,SOCK_DGRAM,0);
- if(sockfd < 0)
- {
- printf("create socket error!\n");
- exit(1);
- }
-
- //填充服务器信息
- bzero(&serv_addr,sizeof(struct sockaddr_in));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(PORT);
- serv_addr.sin_addr.s_addr = inet_addr("192.168.1.132");
-
- //绑定套接字
- if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)) < 0)
- {
- printf("bind error!\n");
- exit(1);
- }
-
- //循环接收网络上发送来的数据并回复消息
- while(1)
- {
- //接收数据
- if(recvfrom(sockfd,buf,MAX_SIZE,0,(struct sockaddr*)&serv_addr,&len) < 0)
- {
- printf("recv error!\n");
- exit(1);
- }
- printf("recv is: %s\n ",buf);
-
-
- printf("write some text:");
- scanf("%s",buffer);
-
- //发送数据
- if(sendto(sockfd,buffer,MAX_SIZE,0,(struct sockaddr*)&serv_addr,len) < 0)
- {
- printf("send error!\n");
- fprintf(stderr,"send error:%s\n",strerror(errno));
- exit(1);
- }
- }
-
- //关闭socket
- close(sockfd);
-
-
- return 0;
- }
- span>
(2)UDP客户端[html] view plain copy
- <span style="font-size:14px;">#include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
-
- #define PORT 3212
- #define MAX_SIZE 512
-
- int main()
- {
- int sockfd;
- int fromlen = sizeof(struct sockaddr);
-
- char buf[MAX_SIZE];
- char buffer[MAX_SIZE];
-
- struct sockaddr_in serv_addr;
-
- //填充服务器信息
- bzero(&serv_addr,sizeof(struct sockaddr_in));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(PORT);
- serv_addr.sin_addr.s_addr = inet_addr("192.168.1.132");
-
- //创建套接字
- sockfd = socket(AF_INET,SOCK_DGRAM,0);
- if(sockfd < 0)
- {
- printf("create socket error!\n");
- exit(1);
- }
-
- //循环发送数据到服务器及接收服务器的回复信息
- while(1)
- {
- printf("enter some text:");
- scanf("%s",buf);
-
- //发送数据
- if(sendto(sockfd,buf,MAX_SIZE,0,(const struct sockaddr*)&serv_addr,sizeof(struct sockaddr)) < 0)
- {
- printf("send error!\n");
- fprintf(stderr,"send error:%s\n",strerror(errno));
- exit(1);
-
- }
-
- //接收数据
- if(recvfrom(sockfd,buffer,MAX_SIZE,0,(struct sockaddr*)&serv_addr,&fromlen) < 0)
- {
- printf("recv error!\n");
- exit(1);
- }
- printf("recv is %s\n",buffer);
- }
-
- //关闭socket
- close(sockfd);
-
- return 0;
- }
- span>