TCP/UDP网络通信

📅 发布时间:2026/7/9 4:30:09 👁️ 浏览次数:
TCP/UDP网络通信
一、协议2/8法则1、计算机中的协议从应用的角度出发协议可以理解为“规则”是数据传输和数据的解释的规则。计算机与计算机之间通过网络实现通信时事先达成的一种约定或规范。是不同的厂商设备、不同的cpu不同的操作系统的计算机只要遵循相同的协议就能实现通讯。2、OSI七层参考模型标准模型Open System Interconnect即开放式系统互联。2.1协议的分层—掌握网络采用分而治之的方法设计将网络的功能划分为不同的模块以分层的形式邮寄组合在一起。网络体系结构即指网络的层次结构和每层所使用的协议的集合二、TCP/IP 4层模型掌握TCP/IP协议族应用层传输层网络层网络接口层三、数据包的传输过程~了解1、封装解封装2.七层模型端对端传输路由器、交换机负责根据目标地址将 数据包转发 到相应的目标设备实现网络通信。选择题因为路由器基于IP设计的俗称三层网络设备//网络层设备交换机是基于以太网设计的俗称二层网络设备//数据链路层设备四、通信模型~了解五、提前量-掌握通信要素协议 本地地址 本地端口 远程地址 远程端口1IP地址Internet Protocol主机在网络中的地址主机要与其他机器通信必须具有一个IP 的地址主机身份证ip地址具有唯一性 192.168.1.101.1IP地址表示形式1.2地址格式转换点分十进制IP转整形IP整形IP转点分十进制字符串IP1.3端口号2.字节序2.1概念——重点小端模式主机字节序低地址存储低位 高地址存储高位大端模式网络字节序 低地址存储高位 高地址存储低位2.2测本机处理器大小端模式——重点方法一 *q%x方法二2.3字节序转换2.3.1主机字节序转换网络字节序2.3.2网络字节序转主机字节序3.套接字理解3.1套接字socketAPI application progress interface3.2套接字通信原理全双工为TCP/IP协议设计的应用层编程接口称为socket API.应用层和传输层之间的一个抽象层是特殊的IO接口在Linux下用于表示进程间网络通信的特殊文件类型。3.3套接字分类标准套接字SOCK_STREAM 流式套接字 TCP--SOCK_GDRAM 数据报套接字UDP--原始套接字//开发的是更底层的应用需要使用需要原始套接字来实现SOCK_RAW 原始套接字六、UDP通信-掌握1、概要UDPUser Datagram Protocol用户数据报协议优点快 比TCP 稍快的传输协议 随时发送数据处理简单高效。缺点不可靠不稳定因为UDP没有TCP那些可靠的机制 在数据传递时如果网络质量不好就会很容易丢包。适用场景无需创建链接所以UDP开销较小数据传输速度快实时性强。多用于对实时性要求较高的通信场合比如视频会议、电话会议。2、套接字API2.1创建套接字socket函数2.2绑定地址信息ip端口协议族ip类型bind 地址信息套接字2.2.1地址结构体2.2.2端口的格式转换htons2.2.3bind函数2.2.4查看修改ip查看ipifconfig修改ipsudo ifconfig eth0 192.168.8.xx(xx范围是1~255)2.3接收数据recvfrom函数size_t unsigned int模拟客户端客户端nc -u 192.168.0.11 8888//192.168.0.11 8888 服务器端的端口示例1注意关心最后两个参数就都接收不关心就都是NULL不能一个NULL 另一个接收的会段错误 接收数据不关心地址信息 NULL NULL示例2 关心对方地址信息2.4INADDR_ANY就是指地址为0.0.0.0的地址任意地址INADDR_ANY已经定义成为一个网络字节序的常量最好使用标准的INADDR_ANY常量而不是直接用0来代替他。让服务器端计算机上的全部网卡的ip地址均可以作为服务器的ip地址也即监听外部客户端程序发送到服务器端全部网卡的网络请求。例如2.5发送数据sendto函数七、TCP如何选用TCP及UDP传输协议——了解特点面向连接 传输层协议能提供可靠的 数据无丢失 数据无失序 数据无重复到达适用于传输质量要求高以及传输大量数据的情况/usr/include/netinet/tcp.h1.TCP报文头格式--了解2.TCP建立连接2.1三次握手2.2双方的状态变化时序图--了解总结3、TCP通信流程--了解确认应答的数据传输在TCP中当发送端数据到达接收主机时接收端主机会返回一个已收到消息的通知。这个消息叫做应答ACK,PositiveAcknowledgement。当发送端将数据发出后会经过特定的时间间隔等待对端的ACK。如果有ACK说明数据已经成功到达对端在发送下一个数据。数据重发八、TCP通信补充1、发送数据send2、接收数据recv#includemy.h int main(int argc ,const char*argv[]) { if(argc!3) { printf(文件错误%s\n,argv[0]); exit(-1); } int cfdsocket(AF_INET,SOCK_STREAM,0); struct sockaddr_in serveraddr; serveraddr.sin_familyAF_INET; serveraddr.sin_porthtons(atoi([2])) serveraddr.sin_addr.s_addrinet_addr(argv[1]); if(connect(cfd,(struct sockaddr*)serveraddr,sizeof(serveraddr)0)) { perror(conect); close(cfd); exit(-1); } char buf[100]good good study ,day day up; send(cfd,buf,sizeof(buf),0); close(cfd); return 0; }#includemy.h int main(int argc,const char*argv[]) { if(argc!3) { printf(文件错误%s\n,argv[0]); exit(-1) } struct sockaddr_in myselfaddr; myselfaddr.sin_fanilyAF_INET; myselfaddr,sin_porthtons(atoi(argv[2])); myselfaddr.sin_addr.s_addrINADDR_ANY; int retbind(sfd,(struct sockaddr*)myselfaddr,sizeof(myselfaddr)); if(ret-1) { perror(bind); exit(-1); closesfd; } int ret_listenlisten(sfd,5); if(ret_listen-1) { perror(listen); close(sfd); exit(-1); } int newconfd accept(sfd,NULL,NULL); if(newconfd-1) { perror(accept); close(sfd); exit(-1); } char buf[100]\0; recv(newconfd,buf,sizeof(buf),0);//read(newconfd,bbuf,sizeof(buf)) puts(buf); close(sfd); return 0; }3、查看修改ipifconfig命令功能查看当前Linux系统的ip地址。ifconfigsudo ifconfig eth0 192.168.8.xx //前三段相同 修改ip xxx范围1~254a3.2两台机器链接同一个wifi3.3ping命令3.4可能出现的问题1没有显示网卡eth02ping不通练习两个机器聊天4.bind报错原因以及解决bind :Address already in use原因1)服务器程序重复执行./s./s2)ctrlc退出服务端就会报错bind :Address already in use2MSL--》1min解决1的等待 2bind 上边调用函数setsockopt5.面试问题如何判断网络连接中对方是否下线read/recv立即返回 返回值为0.read函数返回值九、IO多路复用为什么需要IO多路复用场景一个服务器需要同时处理多个客户端的连接如聊天室、游戏服务器等。如果为每个客户端都创建一个线程/进程来处理当客户端数量非常多时成千上万会消耗大量系统资源。内存、上下文切换开销效率低下。I/O多路复用 就是为了解决这个问题用一个进程/线程来同时监视多个文件描述符如网络套接字socket一旦某个描述符就绪可读、可写或者发生异常就能够通知程序进行相应的读写操作。这样就用单进程/线程实现并发处理多个I/O请求的能力极大地提升了程序的效率。总结1多线程和多进程并发服务器当客户端连接数量特别多的时候消耗的资源特别大效率低。2当客户端连接到时候创建线程断开的时候销毁线程频繁的创建和销毁占用系统开销大。3I/O多路复用可以帮助我们解决上面的问题既能实现服务器支持多客户端又能节省资源降低系统开销。常见的I/O多路复用有三种 select 基于轮询模式、poll、epoll基于事件编程1、概念是linux内核实现一个进程线程同时监控若干文件描述符读写情况这种读写模式称为多路复用。其最大的优势就是系统开销小不必维护这些线程和进程不再由应用程序自己监视文件描述符取而代之由内核替应用程序监视文件2、IO多路复用原理实现套接字异步通信epoll全名eventpoll涉及系统调用epoll_createepoll_ctlepoll_wait1、epoll_create2、epoll_ctl3、epoll_wait实例4、epoll的两种触发方式epoll有两种触发方式LT水平触发和ET边缘触发LT水平触发全称level-triggeredET全称edge-triggeredLT:默认读取方式当epoll通过epoll_wait通知某个fd需要读取数据时如果你没有读取或只读取一部分下次调用epoll_wait时会将这个fd 再次返回给你,LT模式下文件描述符可以是阻塞的或者非阻塞的。容错性较好不容易丢失事件。更易于编程和理解。可以用于多线程程序中多个线程可以共享一个epoll文件描述符。ET高速读取模式当epoll通过epoll_wait通知你某个fd需要读取数据时如果你没有读取或只读取了一部分下次调用epoll_wait时内核默认你知道这个fd需要读取数据不会将这个fd再次返回给你当网络中再有一次数据发送这个fd时才会将这个fd返回给你ET模式下文件描述符必须是非阻塞的。效率更高因为他减少了事件重复通知。需要更加小心的处理每次通知确保从处理所有的数据否则可能会丢失未处理完的数据更适合单线程或者每个线程使用独立epoll文件描述符的场景。5、select poll epoll 的区别重点epoll0 newconfd(500)可读select :0 1 2 3 4 5 ...500轮询6、epoll优缺点优点epoll是linux系统中一种高效的I/O事件通知机制他是select /poll的改进版本属于Linux特有的I/O多路复用技术缺点epoll工作原理十、服务器1、TCP循环服务器同一时刻只能响应一个客户端请求一次处理每个客户端后边的客户端必须等待前面的处理完效率低 等待时间长。1、创建套接字int listenfdsocket2、绑定bind3、listen4、while(1) { //取得客户端连接 int confdaccept(listenfd); dealclient(confd);//处理客户端请求 } void dealclient(int confd) { while(1)//循环处理客户端请求 { } }2、TCP并发服务器同一时刻能响应多个客户端请求 同时处理多客户端 创建进程或线程让新进程或线程处理客户端 原来进程负责连接客户端 效率高。2.1并发服务器之多进程并发1、创建套接字 int listenfdsocket; 2、绑定 bind 3、listen 4、 while(1) { //取得客户端连接 int confdaccept(listenfd); //创建子进程服务客户端 idfork(); if(id0)//子 { dealclient(confd);//处理客户端请求 } } void dealclient(int confd) { while(1)//处理客户端请求 { } }实例使用多进程并发服务器时需要考虑以下几点1、父进程最大文件描述个数父进程中需要close 关闭accept返回的新文件描述符2、系统内创建进程个数与内存大小相关3、进程创建过多是否降低整体服务性能进程调度2.2并发服务器之多线程并发--重点十一、思考题1、如何测试服务器与客户端是否保持连接read/recv返回0只是指示远端正常关闭了连接意味着你可以检测到这一状态但并不代表网络本身完全不可用或者所有网络故障都能被捕捉到。例如连接可能由于网络中断、路由器故障等原因失去响应而这类问题无法通过read返回值直接感知。心跳包主要也就是用于长连接的保活这断线处理。一般的应用下判定时间在30-40秒比较不错。如果实在要求高那就再6-9秒。1、1心跳检测机制作用保活机制1可以帮助我们知道服务器和客户端是否处于连通状态2心跳包可以帮助我们实现长连接即使服务器出现问题客户端自动重新请求连接长连接连接之后一直保持连通状态心跳短链接 频繁的连接和断开1、2具体实现心跳包是由客户端定时发送数据给服务器端的服务器端接收到的心跳包后会对其进行回应如果心跳包发送失败或者长时间没有得到回应就说明连接出现了问题需要及时进行处理。客户端定期每隔0.1秒给服务器发送1包数据服务器收到后回应如果客户端检测到发送了多包数据服务器仍然没有回应说明服务器出问题了客户端重连直到服务器恢复为止。Eg流程服务器功能等待客户端连接。一旦有客户端发送connect 回应ok客户端功能连接成功后每隔0.1秒 发送“connect”接收服务器的“ok”如果长时间收不到ok客户端重新连接服务器。1.3设置TCP属性--了解总结如何测试服务器与客户端是否保持连接--了解1心跳包常见的解决方式就是在程序中加入心跳机制。在接收和发送数据时个人设计一个守护进程线程定时发送心跳包客户端/服务器收到该小包后立刻返回相应的包即可检测对方是否实时在线。2设置TCP属性 TCP 协议自带属性可以设置2.TCP粘包问题2.1长连接与短链接1.长连接client 和server 先建立通讯连接连接建立后不断开然后再进行报文发送和接收。2.短链接client 和server 每进行一次报文收发交易时才进行通讯连接交易完毕后立即断开连接2.2什么时候需要考虑粘包问题1短链接利用TCP每次发送数据就与对方建立连接然后双方发送完一段数据后就关闭连接这样就不会发生粘包问题TCP连接断开后该连接对应的接收缓冲区数据会被内核彻底清理下次重新连接是一个全新的连接拥有全新的缓冲区不能读到上次残留的数据粘包问题通常出现在长连接中因为长连接会持续保持连接状态多个数据包可能会再同一个连接上连续发送导致接收端无法准确判断数据包的边界从而可能出现数据粘连在一块的情况。2在流传输中出现UDP不会出现粘包因为他有消息边界UDP首部有一个UDP长度 记录数据长度TCP是一种流协议stream protocal。这就意味着从应用层角度看数据是以字节流的形式传递给接收者的字节流可以理解为一个双向的通道里流淌的数据。这个数据其实就是我们常说的二进制数据简单来说就是一堆01串 这些01串之间没有任何边界。没有固定的”报文“或者“报文边界”的概念。因此读取TCP数据时我们无法预知再一次指定的读操作中会返回多少字节1、发送端需要等待缓冲区满才发送出去造成给粘包2、接收方不及时接收缓冲区的包造成多个包接收可能发生N次一次就给接收完毕2.3粘包案例客户端write写操作两次产生两个数据包。假设“abc”“def”服务端read读一次可能读到“abcdef”或许是abcd后面的ef在下次被读取到。2.4解决方案解决方案1可以在每个数据报前加一个长度为4 字节的字段。案例发送方数据包123大小不固定变长每次发送数据包时在头部先加长度为4字节的字段接收方每次接收数据时先固定读4字节解析后在得到数据包1的长度然后在读取当读取的数据达到这个长度时说明数据包1已经接收完毕重复后面的操作。解决方法2发送端将每个数据包封装成固定长度不够的可以通过补0来填充这样接收端每次从缓冲区读取固定长度数据就自然而然的把每个数据包拆分开。解决方法3可以在数据包之间设置边界如添加特殊符号这样接收端通过这个边界就可以将不同的数据包拆分开。十二、线程池1、使用线程是如何防止出现大的波峰问法2如果10000个客户端请求处理服务器 12306 -》10.1答意思是如何防止客户端涌来方法是使用线程池线程池具有可以同时提高效率和限制资源使用的好处线程池使用时需要注意设置合理的线程池大小十三、抓包工具Wireshark--会用用来获取网络数据封包包括HTTP、TCP、UDP等网络协议包步骤1获取对方ip步骤2wireshark是捕获机器上的某一块网卡的网络包当你的机器上有多块网卡的时候你需要选择一个网卡。直接双击上面的某个网卡。步骤31、Wireshark窗口2、常见按钮3、过滤表达式的规则3.1协议过滤3.2ip过滤3.3端口过滤3.4逻辑运算符5.wireshark抓到的包十四、TCP和UDP的区别十五、关于ip