当前位置:   article > 正文

网络-TCP/UDP详解_tcp模块给应用层传递下来的data添加上相应的tcp头部信息里面的源端口号

tcp模块给应用层传递下来的data添加上相应的tcp头部信息里面的源端口号

TCP释义:

TCP头部信息字段释义:

在这里插入图片描述

源端口号(Source Port)以及目的端口号(Destination Port):

各占2个字节,端口是传输层和应用层的服务接口,用于寻找发送端和接受端的进程,一般来讲,通过端口号和IP地址,可以唯一确定一个TCP连接,在网络编程中,通常被称为一个socket接口。

序号(Sequence Number ,seq):

占四个字节,用来标识从TCP发送端向TCP接收端发送的数据字节流。 因此,如果数据量过大,超过2^32 那么TCP报文就不再发送。

确认序号(Acknowleged Number ,ack):

占四个字节,包含发送确认的一端所期望收到的下一个序号。因此,确认信号应该是上次已经成功收到数据字节 序号+1 。 该字段只在ACK标志被设置时才有效。

数据偏移(Data Offset):

占4bit ,用于指出TCP首部的长度,若不存在此项,则默认为20字节 ,数据偏移的最大值为60字节((2^4-1)*4)。首部长度实际上也指示了数据区在报文段中的起始偏移值。

保留字段:

占6bit,暂时忽略,值全为0。

标志位:6bit。
  • URG(紧急): 为1时表明紧急指针字段有效。用来保证TCP连接不被中断,并且督促中间层尽快处理这些数据。
  • ACK(确认): 为1时表明确认号字段有效。
  • PSH(推送): 为1时接收方应尽快将报文段交给应用层。所谓push操作就是指在数据包到达接收端以后,立即送给应用程序,不再缓冲区进行排队。
  • RST(复位): 为1时表明TCP连接出现故障必须重建连接。用来复位产生错误的连接,也用来拒绝非法错误和非法数据包。
  • SYN(同步): 在连接建立时用来同步序号。
  • FIN(终止): 为1时表明发送端数据发送完毕,请求释放连接。
接收窗口: 目的主机使用两个字节的窗口字段告诉源主机它每次所期望接收到的字节数。

占两个字节,用于流量控制和拥塞控制,表示当前接收缓冲区的大小。在计算机网络中,通常是用接收方的接收能力的大小来控制发送方的数据发送量。TCP连接的一端根据缓冲区的大小来确定自己的接收窗口值,并且将其告诉对方,使对方可以确定发送数据的字节数。

校验和:

占两个字节,范围包括首部和数据两部分。 用于错误检查。源主机基于部分IP头信息,TCP头信息和数据内容计算一个校验和,目的主机也要进行相同的计算,如果收到的内容没有错误过,两个计算应该是完全一样,从而证明数据的有效性。

紧急指针:

占两个字节,指向数据段内的最后一个字节位置,这个字段只在UDP被设置时才有效。

选项:

是可选的,默认情况不选。

填充:

这个字段中加入额外的0,以确保TCP头部是32的整数倍。

TCP网络通信流程:

在这里插入图片描述

TCP三次握手过程:

在这里插入图片描述

第一步:

客户端TCP向服务端TCP发送一个特殊的TCP报文段,不包含应用层数据。但是报文段首部的SYN标志 会被设置为1,表示此报文段为建立连接的报文段,因此为称为SYN报文段 。另外,客户端会选择一个初始序号,记录此报文段的序列号seq=x 。该报文段会封装在一个IP数据报中被发送到服务器端。这个报文段表达的就是希望建立连接的信息。此时,客户端处于SYN-SENT 阶段。

第二步:

一旦包含SYN报文段的IP数据报到达服务器主机,服务器从IP数据报中提取TCP-SYN报文段,为该TCP连接分配需要的缓存和变量,并向客户端发送表示允许连接的报文段。这个报文段也不包含任何应用层数据,但是包含 三个 重要信息:首先,SYN=1 ,其次该报文段确认序号标志ACK=1,确认序号ack=x+1 最后服务器选择自己的初始序号seq=y , 这个报文表达的就是允许建立该连接,自己的初始序号为y,有时也被称为SYNACK报文段。 此时服务器处于SYN-RCVD (RCVD=received=收到)状态。

第三步:

在收到SYNACK 报文段之后,客户端也要给该连接分配缓存和变量,客户端向服务器再发送一个报文段,对允许连接的报文段进行确认。ACK=1,ack=y+1,seq=x+1 。 并且由于连接已经建立,SYN=0 ,并且已经可以携带被传送到服务器的应用层数据 。 服务器接收到第三次握手消息后,处于ESTAB-LISHED状态,处于ESTAB-LISHED状态就可以进行双向通信。

TCP四次挥手过程-断开TCP连接:

在这里插入图片描述

  • 客户端主动发起第一次挥手,FIN=1,seq=u ,客户端发出挥手消息后处于FIN-WAIT-1 状态。
  • 服务端接收到挥手消息后,发起第二次挥手,ACK=1,ack=u+1,seq=v ,服务端处于CLOSE-WAIT 状态。
  • 客户端接收到第二次挥手消息后,处于FIN-WAIT-2状态 ,即客户端不能给服务端发送消息,服务端可以给客户端发送消息(全双工->单向通行)。
  • 服务端发起第三次挥手,FIN=1,ACK=1, seq=w, ack=u+1 ,服务端处于LAST-ACK 状态。
  • 客户端接收到服务端挥手消息,发起第四次挥手,ACK=1,seq=u+1,ack=w+1, 客户端处于TIME-WAIT 状态。
  • 服务端接收到客户端挥手信息,即进入close 状态,客户端再2MSL时间后由TIME-WAIT状态-》CLOSE状态
为什么要等待呢?

为了这种情况:B向A发送FIN=1的释放连接请求,但是这个报文丢失了,A没有接到不会发送确认信息,那么B就会超时重传,这时A在WAIT-TIME 还能够接收到这个请求,这时在回复一个确认就行了。(A收到FIN=1的请求后WAIT-TIME会重新计时)

深入理解:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这个方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
TCP协议的连接是全双工连接 ,一个TCP连接存在双向的读写通道。
简单来说就是先关读,后关写 ,一共需要四个阶段。以客户机发起关闭连接为例:

  • 服务器读通道关闭。
  • 客户机写通道关闭。
  • 客户机读通道关闭。
  • 服务器写通道关闭。
    关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。
详细过程:
第一阶段:客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i;
  1. 服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道
  2. 客户机收到ACK(i+1) 后,关闭客户机写通道
    此时,客户机仍能通过 读通道 读取服务器的数据,服务器仍能通过写通道写数据。
第二阶段:服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j.
  1. 客户机收到FIN(j) 后,返回确认段ACK,序列号为j+1, 在在TIME-WAIT后才能关闭客户机读通道
  2. 服务器收到ACK(j+1)后,关闭服务器写通道
    这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。

从上面可以看到,主动发起关闭连接操作的一方将达到TIME-WAIT 状态,而且这个状态要保持Maximum Segment Lifetime(生存时间)的两倍时间。为什么要这样做,而不是直接进入CLOSED状态?

  1. 保证TCP协议的全双工连接能够可靠关闭。
    如果Client直接ClOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致server没有收到最后回复的ACK,那么server就会在超时后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后server就会收到PST而不是ACK, server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME-WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。
  2. 保证这次连接的重复数据段从网络消失。
    如果Client直接CLOSED,然后又在向server发起一个新连接,我们不能保证这个新连接与刚关闭的连接端口号是不同的。也就是说有可能新连接的端口和老连接的端口是相同的。一般来说,不会发生什么问题。但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达server,由于新连接和老连接的端口号一致,又因为TCP协议判断不同连接的依据是 socket pair(套接字对),于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的连接的数据包发生混淆。所以TCP连接还要再TIME-WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
同时挥手

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况。
在这里插入图片描述

数据可靠性的体现:
  1. 数据通信前进行连接,通信结束后释放连接。
  2. 保证数据完全到达目的端:确认应答机制和超时重传机制。
  3. 接受方接收的数据都是有序的,根据接收的数据头部的序号+数据的大小,就可确定数据的位置以及下一次接收数据的起始位置。
  4. 数据发送和接收是完全相同的,通过头部的校验和字段来判断接收数据是否存在损坏,存在则丢弃,重新接收客户端的发送(超时重传)。

TCP拥塞控制:

一,拥塞控制和流量控制的区别:

流量控制针对的是点对点之间的(发送方和接受方)之间的速度匹配服务,因为接收方的应用程序读取的速度不一定很迅速,而接受方的缓存是有限的,就需要避免发送的速度过快而导致的问题。
拥塞控制是由于网络中的路由和链路传输速度限制,防止过多的数据注入网络中,要避免网络的过载而进行的控制。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程 ,涉及到所有的主机,路由器,以及与降低网络传输性能有关的所有因素。

二,拥塞控制的几个指导原则:
  1. 一个丢失的报文段意味着拥塞,因此当报文段丢失时应该降低TCP发送方的速率。
  2. 当一个确认的报文段到达时,表示当前网络是顺畅的,即可以提升发送方的速率。
  3. ACK和丢包事件充当隐式的信号,指导着拥塞控制。
三,拥塞控制算法:

拥塞控制是使用拥塞窗口进行控制的,运行在发送方的拥塞控制机制通过跟踪一个额外的变量,即拥塞窗口(cwnd) ,它对于发送方能够快速向网络中发送流量的速率进行了限制,对于发送方: LastByteSent-LastByteAcked<=cwnd

四,拥塞控制代价:

需要获得网络内部流量分布的信息。在实施拥塞控制之前,还需要在结点之间交换信息和各种命令,以便选择控制的策略和实施控制。这样就产生了额外的开销。拥塞控制还需要将一些资源分配给各个用户单独使用,使得网络资源不能更好地实现共享。

拥塞控制算法主要包含的四个部分:

在这里插入图片描述

  • 慢启动
    慢开始算法的思路就是,不要一开始就发送大量的数据,先探测以下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。一般一开始为一个MSS(最大报文段长度),之后翻倍来增加,呈指数增长。
  1. 慢启动过程有一个阈值(ssthresh),一旦达到阈值就进入拥塞避免模式 。这是第一种离开慢启动的方式。
  2. 如果收到一个丢包提示,就将cwnd设为1,并且重新开始慢启动过程,这时要把阈值ssthresh设为当前cwnd值得一半。
  3. 如果收到三次冗余的ACK(没有作用的ACK),就执行一次快速重传并且进入快速恢复状态。
  • 避免拥塞
    进入拥塞避免说明cwnd值大约是上一次遇到拥塞值得一半,这时候不能翻倍,而是将cwnd得值每次增加一个MSS。结束的过程有两种可能:
  1. 当出现超时时,将cwnd值设为一个MSS,并且将ssthresh阈值设为当前cwnd值得一半。
  2. 当收到三个冗余ACK时,将ssthresh阈值设为当前cwnd值的一半,并且将cwnd值设为cwnd值得一半+3 ,即ssthresh 阈值+3并且进入快速恢复状态。
    在这里插入图片描述
  • 快速重传
    快速重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方),而不是等到自己发送数据时捎带确认。
    快速重传算法规定,发送发只要一连受到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计数器时间到期。
    在这里插入图片描述
  • 快速恢复
  1. 当发送方连续收到三个重复确认,就执行“乘法减小” 算法,把慢开始ssthresh阈值减半。这是为了预防网络发生拥塞。请注意:接下来并不执行慢开始算法。
  2. 由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢的线性增大。
    在这里插入图片描述

TCP滑动窗口

概述:

滑动窗口实现了TCP流控制首先明确滑动窗口的范畴:TCP是全双工的协议,会话的双方都可以同时接收和发送数据。TCP会话的双方都各自维护一个发送窗口 和一个 接收窗口 。各自的接收窗口大小取决于应用,系统,硬件的限制 (TCP传输速率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于接收窗口大小。
滑动窗口解决的是流量控制的问题,就是如果接收端和发送端对数据包的处理速度不同,如何让双方达成一致。接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收数据overflow,流量数据是用来解决这个问题的。

窗口的概念:

发送方的发送缓存内的数据可以被分为四类:

  1. 已发送,已收到ACK。
  2. 已发送,未收到ACK。
  3. 未发送,但允许发送。
  4. 未发送,不允许发送。
    其中类型2,3都属于发送窗口。

接收方的缓存数据分为三类:

  1. 已接收。
  2. 未接收,但准备接收。
  3. 未接收,且不准备接收。
    其中类型2属于接收窗口。

窗口大小代表了设备一次能处理多少数据,之后再传给应用层。缓存传给应用层的数据不是乱序的,窗口机制保证了这一点。现实中,应用层可能无法立刻从缓存中读取数据。

滑动机制:
  • 发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
  • 接收窗口只有在前面所有的数据段确认的情况下才会移动左边界。当在前面还有字节未但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此保证发送端会对这些数据重传。
  • 遵循快速重传,累计确认,选择确认等原则。
  • 发送方发windows size=8192 ;就是接收端最多发送8192字节,这个8192一般就是发送方接收缓存的大小。
工作原理理解

在这里插入图片描述
TCP滑动窗口技术通过动态改变窗口大小来调节两台主机间的数据传输。每个TCP/IP主机支持全双工数据传输,因此TCP有两个滑动窗口:一个用来接收数据,另一个用来发送数据。TCP使用ACK确认技术,其确认号指的是下一个所期待的字节。假定发送方设备以每一次三个数据包的方式发送数据,也就是说,窗口大小为3。发送方发送序列号为1,2,3的三个数据包,接受方设备成功接收数据包,用序列号4确认。发送方设备收到确认,继续以窗口大小3发送数据。当接受方设备要求降低或者增大网络流量时,可以对窗口大小进行减小或者增加,本例降低窗口大小为2,每一次发送两个数据包。当接受方设备要求窗口为0,表明接收方已经接收了全部数据,或者接收方应用程序没有时间读取数据,要求暂停发送。发送方接收到携带窗口号为0的确认,停止这一方向的数据传输。
在这里插入图片描述
这里我们可以看到假设窗口的大小是1,也是就每次只能发送一个数据只有接受方对这个数据进行确认了以后才能发送第2个数据。我们可以看到发送方每发送一个数据接受方就要给发送方一个ACK对这个数据进行确认。只有接受到了这个确认数据以后发送方才能传输下个数据。 这样我们考虑一下如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。如果说窗口的大小定义的过大。我们假设发送方一次发送100个数据。但是接收方只能处理50个数据。这样每次都会只对这50个数据进行确认。发送方下一次还是发送100个数据,但是接受方还是只能处理50个数据。这样就避免了不必要的数据来拥塞我们的链路。所以我们就引入了滑动窗口机制,窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小,这个时候链路是否拥护塞。接受方是否能处理这么多数据了。
在这里插入图片描述
首先第一次发送数据时,窗口大小是根据链路带宽大小来确定的。 假设此时窗口为3。这时接收方收到数据以后会对数据进行确认(ACK)告诉发送方我下次希望收到的数据是多少。这里我们看到接收方发送的ACK=3(这是对发送方发送序列2的回答确认,下一次接收方期望接收到的是3序列的信号)。这时,发送方收到这个数据以后就知道我第一次发送的三个数据对方只收到了两个。因此下次从第三个数据开始发。这个时候窗口大小就变成2
在这里插入图片描述
发送方发送了两个数据。
在这里插入图片描述
看到接收方发送的ACK=5,表示他下一次希望收到的数据是5,发送方就知道刚才发送的两个数据被接收,现在开始发送第五个数据。
这就是滑动窗口的工作机制,当链路变好了或者变差了这个窗口还会发生变化,并不是第一次协商好了以后就永远不变。

滑动窗口协议:

滑动窗口协议是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据传输。
只有在接收窗口向前滑动时(此时也发送了确认),发送窗口才有可能向前滑动。
收发两端的窗口按照以上规律不断地向前滑动,因此协议称为滑动窗口协议。
当发送窗口和接收窗口的大小都等于1时,就是停止等待协议。

UDP释义:

  • UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。
  • 它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即时是出现网络拥堵的情况,UDP也无法进行流量控制来避免网络拥塞行为。
  • 传输途中出现丢包,UDPy也不负责重发。
  • 当包达到顺序出现乱序时也没有纠错功能。
  • 如果需要以上的细节控制,那么不得不交由UDP的应用程序去处理。
    在这里插入图片描述
UDP应用场景:
  • 包总量较少的通信(DNS(域名系统),SNMP(简单网络管理协议)等)
  • 视频,音频等多媒体通信(即时通信)
  • 限定于LAN等特定网络中的应用通信
  • 广播通信(广播,多播)

UDP和TCP的区别:

TCP:可靠的,面向连接的,流式服务
UDP:不可靠的,无连接的,数据包服务
  • 不可靠原因:
  • TCP(传输控制协议) 提供的是面向连接,可靠的字节流服务。当客户端和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从另一端传到另一端。
  • UDP(用户数据报协议) 是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不保证它们能到达目的地。由于UDP在传输数据报前不用再客户端和服务器之间建立连接,且没有超时重发等机制,故而传输速度很快。
    由于UDP缺乏拥塞控制,需要基于网络的机制来减少因失控和高速UDP流量负荷而导致的拥塞崩溃效应。换句话说,因为UDP发送者不能够检测拥塞,所以像使用包队列和丢弃技术的路由器这样的网络基本设备往往就成为降低UDP过大通信量的有效工具。数据报拥塞控制协议(DCCP)设计成通过在诸如流媒体类型的高速率UDP流中,增加主机拥塞控制,来减小这个潜在问题。
流式服务:

数据是一条数据源,数据是没有界限的,发送的次数和接收的次数无直接关系。也就write的次数和read的次数无直接联系。
在这里插入图片描述
接收方将数据放在缓冲区,数据一次不能接收完,可以放在缓冲区进行二次读取。

数据包服务:

在这里插入图片描述
发送的次数和接收的次数是相等的。
如果接受端一次未能读取完传输层的数据,剩余的数据将直接丢弃掉。

TCP C/S模型连接代码演示:

服务端:
package Internet.TCPDemo;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //创建一个服务器端口实例
        ServerSocket serverSocket=new ServerSocket();
        //绑定端口
        serverSocket.bind(new InetSocketAddress(8888));
        //监听并获得socket实例,该方法会阻塞
        Socket socket=serverSocket.accept();
        System.out.println(socket.getRemoteSocketAddress()+"  客户端连接上");
        //字符缓冲读取流,用来接收客户端消息
        BufferedReader buffer=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //输出流,用来向客户端发送
        OutputStream outputStream=socket.getOutputStream();
        while(true){
            String s=null;
            while((s=buffer.readLine())!=null){ //因为服务器端调用的是readLine,他看到换行符才会读取结束。
                System.out.println("客户端信息________ " +s);
                //将接收到的消息返回给客户端
                outputStream.write((s+"\n").getBytes());
                outputStream.flush();
            }
        }
        //关闭资源:后开的先关,因为异常抛出,所以下面几个方法报错
        //outputStream.close();
        //buffer.close();
        //socket.close();
        //serverSocket.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
客户端:
package Internet.TCPDemo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;

public class TCPClient {
    public static void main(String[] args) throws IOException {
        //ipconfig dos命令 查找本机ip
        //创建Socket实例
        Socket socket=new Socket();
        //连接服务器
        socket.connect(new InetSocketAddress("127.0.0.1",8888));
        Scanner scanner=new Scanner(System.in);
        //得到输出流实例
        OutputStream outputStream=socket.getOutputStream();
        //得到输入流实例
        BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        while(true){
            String s=scanner.nextLine();//读取标准输入
            //因为服务端是行读,这边写需要加\n
            outputStream.write((s+"\n").getBytes()); //向服务器发送消息
            outputStream.flush();
            String s1=reader.readLine(); //读取服务器返回的消息
            System.out.println("服务器返回消息---》"+s1);
            if(s.equals(s1)){ //比对服务器返回的消息
                System.out.println("服务端成功接收");
                continue;
            }
            System.out.println("数据丢失请重新发送");
        }
        //关闭资源
//        outputStream.close();
//        reader.close();
//        socket.close();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

UDP C/S模型连接代码演示:

服务端:
package Internet.UDPDemo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class UDPServer {
    public static void main(String[] args) {
        try {
            //创建数据报服务端口
            DatagramSocket socket = new DatagramSocket();
            String msg="hello";
            //创建数据报实例
            DatagramPacket packet=new DatagramPacket(msg.getBytes(),msg.length(),new InetSocketAddress("127.0.0.1",666));
            //发送数据报
            socket.send(packet);
        }catch (SocketException e){
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/*
 *  UDP:用户数据包协议:
 *  不可靠的数据传输
 *  数据传输时不会进行事前连接和事后释放。
 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
客户端:
package Internet.UDPDemo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPClient {
    public static void main(String[] args) {
        try {
            //创建socket实例,创建数据报服务端口。
            DatagramSocket socket=new DatagramSocket(666);
            byte [] b=new byte[100];
            //创建数据报实例
            DatagramPacket packet=new DatagramPacket(b,100);
            //接收数据报
            socket.receive(packet);
            System.out.println(new String(b));
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/293906
推荐阅读
相关标签
  

闽ICP备14008679号