Java Socket 编程学习,利用DatagramSocket和DatagramPacket实现UDP数据传输
场景描述:
客户端创建数据包,绑定服务器地址和端口,向服务器发送数据;服务器绑定端口,从端口接受数据
服务器代码:
ServerBean类
package yang.socket.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ServerBean {
// 描述UDP通讯的DatagramSocket对象
private DatagramSocket ds;
// 用来封装通讯字符串
private byte buffer[];
// 服务器端的端口号
private int serverport;
// 通讯内容
private String content;
// 描述通讯地址,此类表示互联网协议 (IP) 地址。
private InetAddress addr;
// 此类实现 IP 套接字地址(IP 地址 + 端口号)
private InetSocketAddress sd;
// 此类表示数据报包
private DatagramPacket dp;
// 以下是各属性的Get和Set类型方法
public DatagramSocket getDs() {
return ds;
}
public void setDs(DatagramSocket ds) {
this.ds = ds;
}
public byte[] getBuffer() {
return buffer;
}
public void setBuffer(byte[] buffer) {
this.buffer = buffer;
}
public int getServerport() {
return serverport;
}
public void setServerport(int serverport) {
this.serverport = serverport;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public InetAddress getAddr() {
return addr;
}
public void setAddr(InetAddress addr) {
this.addr = addr;
}
public InetSocketAddress getSd() {
return sd;
}
public void setSd(InetSocketAddress sd) {
this.sd = sd;
}
public DatagramPacket getDp() {
return dp;
}
public void setDp(DatagramPacket dp) {
this.dp = dp;
}
public ServerBean(int port, InetAddress addr) throws SocketException,
UnknownHostException
{
this.buffer = new byte[1024];
this.serverport = port;
this.content = "";
this.ds = null;
this.setAddr(addr);
this.dp = null;
this.sd = null;
}
public void bind(InetAddress addr, int port) throws SocketException,
UnknownHostException {
// 创建数据报套接字并将其绑定到本地主机上的指定端口
ds = new DatagramSocket(null);
// 创建地址,本地地址
sd = new InetSocketAddress(addr, port);
// 绑定本地地址,在此端口接受消息
ds.bind(sd);
// System.out.println("服务器绑定端口 " + port);
// System.out.println(ds.getLocalSocketAddress());
}
public void listenClient() throws IOException
{
// 在循环体里接收消息
while (true)
{
// 初始化DatagramPacket类型的变量DatagramPacket,用来接收长度为 length 的数据包
dp = new DatagramPacket(buffer, buffer.length);
// 接收消息,并把消息通过dp参数返回
ds.receive(dp);
content = new String(dp.getData(), 0, dp.getLength());
System.out.println(content);
System.out.println("Message From " + dp.getSocketAddress());
}
}
}
UDPServer类
package yang.socket.udp;
import java.io.IOException;
import java.net.InetAddress;
public class UDPServer {
public static int serverport;
public static InetAddress localaddr;
public static void main(String args[]) throws IOException
{
serverport = 1986;
localaddr = InetAddress.getLocalHost();
System.out.println("服务器端启动,绑定端口 " + serverport);
ServerBean server = new ServerBean(serverport, localaddr);
server.bind(localaddr, serverport);
System.out.println("Message Recevied:");
server.listenClient();
}
}
客户端代码:
ClientBean类
package yang.socket.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ClientBean {
// 描述UDP通讯的DatagramSocket对象,表示用来发送和接收数据报包的套接字
private DatagramSocket ds;
// 此类表示数据报包
private DatagramPacket dp;
//此类实现 IP 套接字地址(IP 地址 + 端口号)
private InetSocketAddress sd;
// 用来封装通讯字符串
private byte buffer[];
// 客户端的端口号
private int clientport;
// 服务器端的端口号
private int serverport;
// 通讯内容
private String content;
// 描述通讯地址,此类表示互联网协议 (IP) 地址。
private InetAddress localaddr;
private InetAddress serveraddr;
// 以下是各属性的Get和Set类型方法
public DatagramSocket getDs() {
return ds;
}
public void setDs(DatagramSocket ds) {
this.ds = ds;
}
public DatagramPacket getDp() {
return dp;
}
public void setDp(DatagramPacket dp) {
this.dp = dp;
}
public InetSocketAddress getSd() {
return sd;
}
public void setSd(InetSocketAddress sd) {
this.sd = sd;
}
public byte[] getBuffer() {
return buffer;
}
public void setBuffer(byte[] buffer) {
this.buffer = buffer;
}
public int getClientport() {
return clientport;
}
public void setClientport(int clientport) {
this.clientport = clientport;
}
public int getServerport() {
return serverport;
}
public void setServerport(int serverport) {
this.serverport = serverport;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public InetAddress getLocaladdr() {
return localaddr;
}
public void setLocaladdr(InetAddress localaddr) {
this.localaddr = localaddr;
}
public InetAddress getServeraddr() {
return serveraddr;
}
public void setServeraddr(InetAddress serveraddr) {
this.serveraddr = serveraddr;
}
public ClientBean(int clientport, int serverport, InetAddress serveraddr, InetAddress localaddr) throws SocketException,
UnknownHostException
{
this.buffer = new byte[1024];
this.clientport = clientport;
this.serverport = serverport;
this.content = "";
this.ds = null;
this.serveraddr = serveraddr;
this.localaddr = localaddr;
this.dp = null;
this.sd = null;
}
public void bind(InetAddress addr, int clientport) throws SocketException, UnknownHostException{
// 创建数据报套接字并将其绑定到本地主机上的指定端口
ds = new DatagramSocket(null);
//创建地址,本地地址
sd = new InetSocketAddress(addr, clientport);
//将此 DatagramSocket 绑定到特定的地址和端口
ds.bind(sd);
}
public void sendToServer() throws IOException
{
buffer = content.getBytes();
// 构造数据报包,用来将长度为 length的包发送到指定主机上的指定端口号。
dp = new DatagramPacket(buffer, content.length(), serveraddr, serverport);
// 发送数据包
ds.send(dp);
}
}
UDPClient类
package yang.socket.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
public class UDPClient implements Runnable
{
public static String content;
public static int clientport;
public static int serverport;
public static InetAddress serveraddr;
public static InetAddress localaddr;
public static ClientBean client;
public void run()
{
try
{
// 设置发送消息体内容
client.setContent(content);
// 发送消息
client.sendToServer();
}
catch (Exception ex)
{
System.err.println(ex.getMessage());
}
}
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
clientport = 1985;
serverport = 1986;
//发送的serverIP地址
byte[] bs = new byte[] { (byte) 192, (byte) 168, (byte) 30, (byte) 13 };
serveraddr = InetAddress.getByAddress(bs);
localaddr = InetAddress.getLocalHost();
client = new ClientBean(clientport, serverport, serveraddr, localaddr);
//讲套接字绑定到本地
client.bind(localaddr, clientport);
System.out.println("客户端启动");
System.out.print("Server Address: ");
//获取套接字连接的地址
System.out.print("HostName " + client.getServeraddr().getHostName());
System.out.print(" Address " + client.getServeraddr().getHostAddress());
System.out.print(" Port " + client.getServerport() + "\n");
System.out.print("Local Address: ");
//获取套接字绑定的本地地址
System.out.print("HostName " + client.getDs().getLocalAddress().getHostName());
System.out.print(" Address " + client.getDs().getLocalAddress().getHostAddress());
System.out.print(" port " + client.getDs().getLocalPort() + "\n");
System.out.println("请输入发送内容,回车发送,键入end时发送结束");
while (true)
{
// 接收用户输入
content = br.readLine();
// 如果是end或空,退出循环
if (content == null || content.equalsIgnoreCase("end")
|| content.equalsIgnoreCase(""))
{
break;
}
// 开启新线程,发送消息
// 每次输入一次消息,就新建一个线程和连接
new Thread(new UDPClient()).start();
}
System.out.println("连接套接字断开关闭");
client.getDs().disconnect();
client.getDs().close();
}
}
测试运行:
UDPClient
客户端启动
Server Address: HostName Lenovo-PC Address 192.168.30.13 Port 1986
Local Address: HostName Lenovo-PC Address 192.168.30.13 port 1985
请输入发送内容,回车发送,键入end时发送结束
nihao
this is a udp test
end
连接套接字断开关闭
UDPServer
服务器端启动,绑定端口 1986
Message Recevied:
nihao
Message From /192.168.30.13:1985
this is a udp test
Message From /192.168.30.13:1985