JAVA网络编程个人笔记 第8章 UDPSocket编程
- UDPSocket
- UDP套接字编程简介
- UDP客户端编程步骤
- TCP客户端编程步骤
- DatagramSocket与DatagramPacket
- DatagramPacket的使用
- DatagramSocket类
- 构造方法
- 其他方法
- DatagramPacket类
- 构造方法
- 其他方法
- DatagramPacket地址处理方法
- DatagramPacket数据处理方法
- UDP通信编程步骤
UDPSocket
UDP套接字编程简介
JAVA通过DatagramPacket类和DatagramSocket类使用UDP套接字
- 客户端和服务器端都通过DatagramSocket的send()方法和receive()方法来发送和接受数据
- 客户端和服务器端用DatagramPacket来包装需要发送或者接收到的数据
UDP客户端编程步骤
UDP编程的客户端一般步骤是:
- 创建一个socket,用函数socket();
- 设置socket属性,用函数setsockopt();* 可选
- 绑定IP地址、端口等信息到socket上,用函数bind();* 可选
- 设置对方的IP地址和端口等属性;
- 发送数据,用函数sendto();
- 关闭网络连接
TCP客户端编程步骤
- 创建一个socket,用函数socket();
- 设置socket属性,用函数setsockopt();* 可选
- 绑定IP地址、端口等信息到socket上,用函数bind();* 可选
- 设置要连接的对方的IP地址和端口等属性;
- 连接服务器,用函数connect();
- 收发数据,用函数send()和recv(),或者read()和write();
- 关闭网络连接;
DatagramSocket与DatagramPacket
- 发送信息时,JAVA创建一个包含待发送信息的DatagramPacket实例,并将其作为参数传递给DatagramSocket实例的send()方法
- 接收信息时,JAVA程序首先创建一个DatagramPacket实例,该实例预先分配了一些空间,并将接收到的信息存放在该空间中,然后把该实例作为参数传递给DatagramSocket实例的receive()方法
DatagramPacket的使用
- 在创建DatagramPacket实例时,如果该实例用来包装待接收的数据,则不指定数据来源的远程主机和端口,只需指定一个缓存数据的byte数组即可(在调用receive()方法接收到数据后,原地址和端口等信息会自动包含在DatagramPacket实例
例如用于接收数据报的DatagramPacket构造方法为:
DatagramPacket(byte[] buf,int length)
- 在创建DatagramPacket实例时,如果该实例用来包装待发送的数据,则要指定要发送到的目的主机和端口
例如用于发送数据的DatagramPacket构造方法为:
DatagramPacket(byte[] buf,int length,InetAddress address, int port)
DatagramSocket类
构造方法
- public DatagramSocket()构造一个数据报socket,并使其与本地主机任一可用的端口连接。若打不开socket则抛出SocketException异常
- public DatagramSocket(int port)构造一个数据报socket,并使其与本地主机指定的端口连接。若打不开sockett或socket无法与指定端口连接则抛出SocketException异常
其他方法
- public void close()
- public int getLocalPort()返回本地套接字的正在监听的端口
- public void send(DatagramPacket p)发送数据包,出错时会发生IOException异常
- public viod receive(DatagramPacket p)从网络上接收数据包并将其存储在对象p中
- p中的数据缓冲区必须足够大,receive()把尽可能多的数据存放在p中,如果装不下,就把其余的部分丢弃。接收数据出错时会抛出IOException异常
DatagramPacket类
除传输信息本身外,每个DatagramPacket实例中还附加了地址和端口信息,其具体含义取决于该数据报文是被发送还是被接收
- 若是要发送的数据报文,DatagramPacket实例中的地址则指明了目的地址和端口号,若是接收到的数据报文,DatagramPacket实例中的地址则指明了所收信息的源地址
- 因此,服务器端可以修改接收到的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,SocketAddress sockAddr)
- DatagramPacket(byte[] data,int offset,int length,SocketAddress sockAddr)
其他方法
- 以上构造方法都创建一个数据部分包含在指定的字节数组中的数据报中
- 前两种形式的构造方法主要用来创建接收端的DatagramPacket实例
- 后四种形式主要用来创建发送端的DatagramPacket实例
- 如果指定了offset,数据报文的数据部分将从字节数据的指定位置发送或接收数据
- length参数指定了字节数组中在发送时要传输的字节数,或在接收数据时所能接收的最多字节数。length参数可能比data.length小,但是不能比他大
DatagramPacket地址处理方法
- InetAddress getAddress()
- void setAddress(InetAddress address)
- int getPort()
- void setPort(int port)
- SocketAddress getSocketAddress()
- void setSocketAddress(SocketAddress sockAddr)
DatagramPacket数据处理方法
- int getLength()
- void setLength(int length)
- int getOffset()
- getOffset()方法返回发送或接收的数据存放在缓存区时的偏移量。不存在setOffset()方法,不过可以用setData()方法来设置偏移量
- byte[] getData()
- getData()方法返回与数据报文相关联的字节数组。实际返回的是对于DatagramPacket最近关联的字节数组的一个引用,而关联则是通过构造函数或setData()方法形成
- 返回的缓存数组的长度可能比数据报文内部长度更长,因此,必须使用内部长度和偏移量来指定实际接收到的信息
- void setData(byte[] data)
- void setData(byte[] buffer,int offset,int length)
- setData()方法指定一个字节数组作为该数据报文的数据部分。第一种形式将整个字节数组作为缓冲区;第二种形式吧字节数组中,从offset到offset+length-1的部分作为缓冲区。每次调用第二种形式的setData()方法,都将更新数据的内部偏移量和长度
UDP通信编程步骤
UDP客户端首先向被动等待联系的服务器发送一个数据报文
- 创建一个DatagramSocket实例,可以有选择对本地地址和端口号进行设置,如果设置了端口号,则客户端会在该端口号上监听从服务器端发送来的数据
- 使用DatagramSocket实例的send()和receive()方法来发送和接收DatagramPacket实例,进行通信
- 通信完成后,调用DatagramSocket实例的close()方法来关闭该套接字
UDP服务器为所有通信使用同一套接字,这点与TCP服务器不同
- 创建一个DatagramSocket实例,指定本地端口号,并可以有选择地指定本地地址,此时,服务器已经准备好从任何客户端接收数据报文
- 使用DatagramPacket实例的receive()方法接收一个DatagramPacket实例,当receive()方法返回时,数据报文就包含了客户端的地址,这样就知道了回复信息应该发送到什么地方
- 使用DatagramSocket实例的send()方法向服务器端返回DatagramPacket实例