tcp是双向的吗(tcp双向通信协议详解)

      最后更新:2024-02-15 22:39

      UDP、TCP 协议的区别?

      一、TCP协议TCP位于传输层, 提供可靠的字节流服务。所谓的字节流服务(Byte Stream Service) 是指, 为了方便传输, 将大块数据分割成以报文段(segment) 为单位的数据包进行管理。 而可靠的传输服务是指, 能够把数据准确可靠地传给对方。 即TCP 协议为了更容易传送大数据才把数据分割, 而且 TCP 协议能够确认数据最终是否送达到对方。所以,TCP连接相当于两根管道(一个用于服务器到客户端,一个用于客户端到服务器),管道里面数据传输是通过字节码传输,传输是有序的,每个字节都是一个一个来传输。(1)、三次握手:握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和ACK(acknowledgement) 。第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,完成三次握手。若在握手过程中某个阶段莫名中断, TCP 协议会再次以相同的顺序发送相同的数据包。(2)、四次挥手:由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。先进行关闭的一方将执行主动关闭,而另一方被动关闭。客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。服务器B关闭与客户端A的连接,发送一个FIN给客户端A。客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。三次握手和四次挥手:在TCP连接中,服务器端的SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中, B端向A端发送的ACK和FIN是分两次发送的。因为在B端接收到A端的FIN后, B端可能还有数据要传输,所以先发送ACK,等B端处理完自己的事情后就可以发送FIN断开连接了。(3)、深入理解TCP连接:由于TCP是全双工的,因此在每一个方向都必须单独关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这个方向上没有数据流动,一个TCP连接在接收到一个FIN后仍能发送数据。 首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。简单来说,是“先关读,再关写” ,总共需要4个阶段。以客户机发起关闭连接为例:1.服务器读通道关闭;2.客户端写通道关闭;3.客户端读通道关闭;4.服务器写通道关闭。关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段,直到接收到对方发送的FIN,且对方收到了接收确认的ACK之后,双方的数据通信完全结束,过程中每次都需要返回确认数据段ACK。(4)、TCP使用滑动窗口机制来进行流量控制。建立连接时,各端分配一个缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端。接收方发送的确认消息中包含了自己剩余的缓冲区尺寸。剩余缓冲区空间的数量叫做窗口。其实就是建立连接的双虎互相知道彼此剩余的缓冲区大小。(5)、拥塞控制拥塞控制:防止过多的数据注入到网路中,这样可以使网络中的路由器或链路不至于阻塞。拥塞控制是一个全局性的过程,和流量控制不同,流量控制是点对点的控制。1、慢开始:发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态的变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接收方的接收能力,发送窗口可能小于拥塞窗口。思路就是:不要一开始就发送大量的数据,先试探一下网络的拥塞程度,也就是说由小到大增加拥塞窗口的大小。为了防止cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。 ssthresh的方法如下:当cwnd < ssthresh时,开始使用慢开始算法;当cwnd > ssthresh, 改用拥塞避免算法;当cwnd = ssthresh时,慢开始与拥塞算法任意。2.拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按照线性规律缓慢增长。无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为⽆法判定,所以都当作拥塞处理),就把慢开始门限设置为出现拥塞时的发送窗口的一半,然后把拥塞窗口设置为1,执行慢开始算法:此外,还有快速重传和快速恢复,停止-等待协议,回退N帧协议,选择重传协议等。二、UDP协议:无连接协议,也称透明协议,也位于传输层。三、两者区别:1) TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。2) TCP提供可靠的传输(有序,无差错,不丢失,不重复); UDP提供不可靠的传输。3) TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。4) TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。四、长连接和短连接HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠的、面向连接的。在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:Connection:keep-alive在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
      udp 和tcp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输,而 udp 则常被用于让广播和细节控制交给应用的通信传输。两者的区别大致如下:tcp 面向连接,udp 面向非连接即发送数据前不需要建立链接;tcp 提供可靠的服务(数据传输),udp 无法保证;tcp 面向字节流,udp 面向报文;tcp 数据传输慢,udp 数据传输快; tcp 为什么要三次握手,为什么? 我们假设A和B是通信的双方。我理解的握手实际上就是通信,发一次信息就是进行一次握手。第一次握手:A给B打电话说,你可以听到我说话吗?第二次握手:B收到了A的信息,然后对A说:我可以听得到你说话啊,你能听得到我说话吗?第三次握手:A收到了B的信息,然后说可以的,我要给你发信息啦!在三次握手之后,A和B都能确定这么一件事:我说的话,你能听到;你说的话,我也能听到。这样,就可以开始正常通信了。 注意:HTTP是基于TCP协议的,所以每次都是客户端发送请求,服务器应答,但是TCP还可以给其他应用层提供服务,即可能A、B在建立链接之后,谁都可能先开始通信。如果采用两次握手,那么只要服务器发出确认数据包就会建立连接,但由于客户端此时并未响应服务器端的请求,那此时服务器端就会一直在等待客户端,这样服务器端就白白浪费了一定的资源。若采用三次握手,服务器端没有收到来自客户端的再此确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器的资源。
      tcp和udp协议有什么区别? TCP(传输控制协议)和 UDP(用户数据报协议)的区别如下:1. TCP协议在传送数据段的时候要给段标号;UDP协议不需要2. TCP协议可靠;UDP协议不可靠3. TCP协议是面向连接;UDP协议采用无连接4. TCP协议负载较高,采用虚电路;UDP采用无连接5. TCP协议的发送方要确认接收方是否收到数据段(3次握手协议)6. TCP协议采用窗口技术和流控制7. TCP的速度较慢,UDP 较快。
      UDP、TCP 协议的区别?

      TCP双向通信

      socket通信(服务器端)#include#include#include#pragma comment(lib,"ws2_32.lib")#includeDWORD WINAPI clientThread(LPVOID lpParameter){int sockfd = (int)lpParameter;char caMsg[1024] = {''};while(1){memset(caMsg,0,sizeof(caMsg));scanf("%s",caMsg);int ret = send(sockfd,caMsg,strlen(caMsg),0);if(SOCKET_ERROR == ret){printf("send errrorn");}}return 0;}int main(void){WORD sockVersion = MAKEWORD(2,2);WSADATA wsaData;if(WSAStartup (sockVersion ,&wsaData )!= 0){return 0;}SOCKET Server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(Server == INVALID_SOCKET ){printf("create socket failed!");system("pause");return 0;}struct sockaddr_in serverAddr;serverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(888);serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");if(bind(Server,(LPSOCKADDR)&serverAddr,sizeof(serverAddr))==SOCKET_ERROR){perror("bind failed!");exit(EXIT_FAILURE);}if(listen(Server,10)==SOCKET_ERROR){printf("listen error!");return 0;}struct sockaddr_in clientAddr;int clientSockfd = -1;int iLen = sizeof(clientAddr);while(1){printf("Accept connect ... n");clientSockfd = accept(Server,(struct sockaddr*)&clientAddr,&iLen);if(-1 == clientSockfd){perror("accept");break;}printf("client ip:%s,port:%u n",inet_ntoa(clientAddr.sin_addr) ,clientAddr.sin_port);CreateThread(NULL,0,clientThread,(LPVOID)clientSockfd,0,NULL);char recvData[128];while(1){int ret = recv(clientSockfd,recvData,128,0);if(ret > 0){printf(" recv data:%sn",recvData);}}}closesocket(Server);return 0;}客户端:#include#include#include#pragma warning(disable:4068)#pragma comment(lib,"ws2_32.lib")#includeDWORD WINAPI serverThread(LPVOID lpParameter){int sockfd = (int)lpParameter;char caMsg[128] = {''};while(1){int ret = recv(sockfd,caMsg,128,0);if(ret > 0){printf("recv data: %sn",caMsg);}memset(caMsg,0,sizeof(caMsg));}}int main(void){WORD sockVersion = MAKEWORD(2,2);WSADATA data;if(WSAStartup (sockVersion,&data)!=0){return 0;}SOCKET sclient = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sclient==INVALID_SOCKET){printf("invalid socket !");return 0;}struct sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_port = htons(888);servAddr.sin_addr.S_un.S_addr = inet_addr ("127.0.0.1");if(connect(sclient,(struct sockaddr*)&servAddr,sizeof(servAddr))== SOCKET_ERROR){printf("connect error!");closesocket(sclient);return 0;}printf("Connect success n");CreateThread(NULL,0,serverThread,(LPVOID)sclient,NULL,0);char caMsg[128];while(1){memset(caMsg,0,sizeof(caMsg));scanf("%s",caMsg);int ret = send(sclient,caMsg,128,0);}closesocket(sclient);WSACleanup();return 0;}
      TCP双向通信

      tcp是一对一还是一对多

      tcp是一对一。简介传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。互联网络与单个网络有很大的不同,因为互联网络的不同部分可能有截然不同的拓扑结构、带宽、延迟、数据包大小和其他参数。TCP的设计目标是能够动态地适应互联网络的这些特性,而且具备面对各种故障时的健壮性。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
      tcp是一对一还是一对多

      如何实现上位机和下位机之间的无线通讯?

      用wifi还是有线那是系统的事,你要做的就是保证上位机下位机能加入同一网络就可以了(或者上位机用公网地址,下位机能经过局域网访问互联网)
      需要查你所用的操作系统的网络通信API,常用的协议就是UDP和TCP,UDP最简单,但是无连接不可靠,TCP较复杂,但是有连接且可靠。 对于UDP Server来说,涉及的函数为:socket(); 地址分配; bind(); recvfrom(); sendto();对于UDP Client来说,涉及的函数为:socket(); 地址分配; bind(); sendto(); recvfrom();BTW,如果UDP需要做成双向通信的话,可以使用bidirectional UDP,即在client中分配地址时既分配自己地址,也分配server地址;否则,需要分别建立两套socket来进行UDP的双向通信。对于TCP Server来说,涉及的函数为:socket(); 地址分配; bind(); listen(); accept(); read(); write()对于TCP Client来说,涉及的函数为:socket(); 地址分配; connect(); write(); read() TCP是有连接的,建立了连接就往自己建立的socket里写或者读数据即可,对方一定能收到,没有bidirectional的概念,TCP就是双向的。
      如何实现上位机和下位机之间的无线通讯?

      tcp是全双工还是半双工

      全双工传输 英文写法是:Full-Duplex Transmissions是指交换机在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。目前的交换机都支持全双工。全双工的好处在于迟延小,速度快。 与之对应的是【半双工】这个概念:就是指一个时间段内只有一个动作发生,举个简单例子,一天窄窄的马路,同时只能有一辆车通过,当目前有两量车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开,这个例子就形象的说明了半双工的原理。早期的对讲机、以及早期集线器等设备都是实行半双工的产品。
      tcp是全双工还是半双工

      本文由 在线网速测试 整理编辑,转载请注明出处。

          热门文章

          文章分类