基本套接字:UDP 套接字

news/2024/5/18 11:52:34 标签: java, Java, JAVA, socket, Socket, SOCKET, udp, UDP

UDP套接字

 

UDP协议提供了一种不同于TCP协议的端到端服务。实际上UDP协议只实现两个功能:1)在IP协议的基础上添加了另一层地址(端口),2)对数据传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据。由于其简单性,UDP套接字具有一些与我们之前所看到的TCP套接字不同的特征。例如,UDP套接字在使用前不需要进行连接。TCP协议与电话通信相似,而UDP协议则与邮件通信相似:你寄包裹或信件时不需要进行"连接",但是你得为每个包裹和信件指定目的地址。类似的,每条信息(即数据报文,datagram负载了自己的地址信息,并与其他信息相互独立。在接收信息时,UDP套接字扮演的角色就像是一个信箱,从不同地址发送来的信件和包裹都可以放到里面。一旦被创建,UDP接字就可以用来连续地向不同的地址发送信息,或从任何地址接收信息。

UDP套接字与TCP套接字的另一个不同点在于他们对信息边界的处理方式不同:UDP套接字将保留边界信息。这个特性使应用程序在接受信息时,从某些方面来说比使用TCP套接字更简单。(第2.3.4节将进一步讨论这个问题)最后一个不同点是,UDP协议所提供的端到端传输服务是尽力而为(best-effort)的,即UDP套接字将尽可能地传送信息,但并不保证信息一定能成功到达目的地址,而且信息到达的顺序与其发送顺序不一定一致(就像通过邮政部门寄信一样)。因此,使用了UDP套接字的程序必须准备好处理信息的丢失和重排。(稍后我们将给出一个这样的例子)

既然UDP协议为程序带来了这个额外的负担,为什么还会使用它而不使用TCP协议呢?原因之一是效率:如果应用程序只交换非常少量的数据,例如从客户端到服务器端的简单请求消息,或一个反方向的响应消息,TCP连接的建立阶段就至少要传输其两倍的信息量(还有两倍的往返延迟时间)。另一个原因是灵活性:如果除可靠的字节流服务外,还有其他的需求,UDP协议则提供了一个最小开销的平台来满足任何需求的实现。

JAVA.html" title=Java>Java程序员通过DatagramPacket   类和 DatagramSOCKET.html" title=Socket>Socket类来使用UDP套接字。客户端和服务器端都使用DatagramSOCKET.html" title=Socket>Sockets来发送数据,使用DatagramPackets来接收数据。

  

 DatagramPacket

TCP协议发送和接收字节流不同,UDP终端交换的是一种称为数据报文的自包含self-contained)信息。这种信息在JAVA.html" title=Java>Java中表示为DatagramPacket类的实例。发送信息时,JAVA.html" title=Java>Java程序创建一个包含了待发送信息的DatagramPacket实例,并将其作为参数传递给DatagramSOCKET.html" title=Socket>Socket类的send()方法。接收信息时,JAVA.html" title=Java>Java程序首先创建一个DatagramPacket实例,

该实例中预先分配了一些空间(一个字节数组byte[]),并将接收到的信息存放在该空间中。然后把该实例作为参数传递给DatagramSOCKET.html" title=Socket>Socket类的receive()方法。

除传输的信息本身外,每个DatagramPacket实例中还附加了地址和端口信息,其具体含义取决于该数据报文是被发送还是被接收。若是要发送的数据报文, DatagramPacket例中的地址则指明了目的地址和端口号,若是接收到的数据报文, DatagramPacket实例中的地址则指明了所收信息的源地址。因此,服务器端可以修改接收到的DatagramPacket例的缓存区内容,再将这个实例连同修改后的信息一起,发回给它的源地址。在DatagramPacket的内部也有lengthoffset字段,分别定义了数据信息在缓存区的起始位置和字节数。请参考下面的介绍和第2.3.4节的内容,以避免在使用DatagramPackets时易犯的一些错误。

DatagramPacket:   创建

DatagramPacket(byte[ ] data, int length)

DatagramPacket(byte[ ] data, int offset, int length)

DatagramPacket(byte[ ] data, int length, InetAddress 

remoteAddr, int remotePort)

DatagramPacket(byte[ ] data, int offset, int length, 

InetAddress remoteAddr, int remotePort)

DatagramPacket(byte[ ] data, int length, SOCKET.html" title=Socket>SocketAddress

sockAddr)

DatagramPacket(byte[ ] data, int offset, int length, 

SOCKET.html" title=Socket>SocketAddress sockAddr) 

以上构造函数都创建一个数据部分包含在指定的字节数组中的数据报文,前两种形式的构造函数主要用来创建接收的端的DatagramPackets实例,因为没有指定其目的地址(尽管可以通过setAddress()setPort()方法,或setSOCKET.html" title=Socket>SocketAddress()方法来指定)。后四种形式主要用来创建发送端的DatagramPackets实例。 

如果指定了offset,数据报文的数据部分将从字节数组的指定位置发送或接收数据。length参数指定了字节数组中在发送时要传输的字节数,或在接收数据时所能接收的最多字节数。length参数可能比data.length小,但不能比它大。目的地址和端口号可以分别设置,或通过SOCKET.html" title=Socket>SocketAddress同时设置。

DatagramPacket:   地址处理

InetAddress getAddress()

void setAddress(InetAddress address)

int getPort()

void setPort(int port)

SOCKET.html" title=Socket>SocketAddress getSOCKET.html" title=Socket>SocketAddress()

void setSOCKET.html" title=Socket>SocketAddress(SOCKET.html" title=Socket>SocketAddress sockAddr)

除了构造函数外,以上方法提供了另外一些方法来访问和修改DatagramPacket实例的地址信息。另外需要注意,DatagramSOCKET.html" title=Socket>Socketreceive()方法是将其地址和端口设置为数据报发送者的地址和端口。

DatagramPacket:   处理数据

int getLength()

void setLength(int length)

int getOffset()

byte[ ] getData()

void setData(byte[ ] data)

void setData(byte[ ] buffer, int offset, int length)

前两个方法返回和设置数据报文中数据部分的内部长度。此内部长度可以通过其构造函数或setLength()方法显式地设定。若试图将其设置得比相关联的缓存区长度更大,程序将抛出一个IllegalArgumentException异常。DatagramSOCKET.html" title=Socket>Socket类的receive()方法在两个方面使用内部长度:在输入时,用来指定接收到的将被复制到缓冲区的消息的最长字节数,在返回时,用来指示实际存入缓冲区的字节数。

getOffset()方法返回发送或接收的数据存放在缓存区时的偏移量。不存在setOffset()法,不过可以使用setData()方法来设置偏移量。

getData()方法返回与数据报文相关联的字节数组。实际返回的是对与DatagramPacket最近关联的字节数组的一个引用,而关联则是通过构造函数或setData()方法形成。返回的缓存数组的长度可能比数据报文内部长度更长,因此,必须使用内部长度和偏移量来指定实际接收到的信息。

setData()方法指定一个字节数组作为该数据报文的数据部分。第一种形式将整个字节数组作为缓冲区;第二种形式把字节数组中,从offsetoffset+length-1的部分作为缓存区。每次调用第二种形式的setData()方法,都将更新数据的内部偏移量和长度。

相关下载:

JAVA.html" title=Java>Java_TCPIP_SOCKET.html" title=Socket>Socket编程(doc)

http://download.csdn.net/detail/undoner/4940239

 

文献来源:

UNDONER(小杰博客) :http://blog.csdn.net/undoner

LSOFT.CN(琅软中国) :http://www.lsoft.cn

 


http://www.niftyadmin.cn/n/1853266.html

相关文章

前端常见的浏览器兼容性问题及解决方案

常见的兼容性问题: 1、不同浏览器的标签默认的外补丁( margin )和内补丁(padding)不同解决方案: css 里增加通配符 * { margin: 0; padding: 0; }2、IE6双边距问题;在 IE6中设置了float , 同时又设置margin , 就会出现边距问题解决方案&#…

基本套接字:UDP 客户端/服务器端

UDP客户端 UDP客户端首先向被动等待联系的服务器端发送一个数据报文。一个典型的UDP客户端主要执行以下三步: 1. 创建一个DatagramSocket实例,可以选择对本地地址和端口号进行设置。 2. 使用DatagramSocket类的send() 和 receive()方法来发送和接收…

【win10】更改资源管理器显示:快速访问和此电脑

通常,我习惯通过按 winE来打开资源管理器,然后显示各个分区并进行操作。在win10打开资源管理器默认显示的是快速访问,并不是显示的分区。下面是修改步骤。 1、按WinE打开资源管理器,点击【查看】->【选项】->【更改文件夹和…

Linux下nacos报unknown system variable ‘tx_read_only‘

说明:我这边linux上使用的时mysql8.0.23,nacos是1.1.3 这个问题是因为mysql-connector-java驱动包与数据库的版本不一致导致的,所以需要下载对应的mysql连接驱动包 官方下载地址:https://mvnrepository.com/artifact/mysql/mysql…

信息编码:基本整型

信息编码 首先,我们来考虑一下简单数据类型,如int,long,char,String等,是如何通过套接字发送和接收的。从前面章节我们已经知道,传输信息时可以通过套接字将字节信息写入一个OutputStream实例中…

MySql安装和基本管理

阅读目录 概览  插入数据  更新数据  删除数据  查询数据返回顶部概览 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入UPDATE实现数据的更新使用DELETE实现数据的…

信息编码:字符串和文本

字符串和文本 历史悠久的文本(可打印,即可显示的字符串)可能是用来表示信息最常用的方式。文本使用起来非常方便,因为人们习惯于处理各种各样以字符串形式表示的信息,如书本中,报纸中,以及电脑显…

信息编码:位操作布尔值编码

位操作:布尔值编码 位图(Bitmaps)是对布尔信息进行编码的一种非常紧凑的方式,通常用在协议中。位图的主要思想是整型数据中的每一位都能够对一个布尔值编码--通常是0表示false,1表示true。要操纵位图,你需要…