Java 利用Socket实现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() throws SocketException,
UnknownHostException {
// 创建数据报套接字并将其绑定到本地主机上的指定端口
ds = new DatagramSocket(null);
// 创建地址,本地地址
sd = new InetSocketAddress(addr, serverport);
// 绑定本地地址,在此端口接受消息
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());
if(content.equalsIgnoreCase("end")){
System.out.println("The Message is over, client socket has closed.");
}
}
}
}
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();
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() throws SocketException, UnknownHostException{
// 创建数据报套接字并将其绑定到本地主机上的指定端口
ds = new DatagramSocket(null);
//创建地址,本地地址
sd = new InetSocketAddress(localaddr, 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;
import java.net.SocketException;
import java.net.UnknownHostException;
class ClientBeanThread implements Runnable{
private ClientBean client;
public ClientBeanThread(int clientport, int serverport, InetAddress serveraddr, InetAddress localaddr) throws SocketException, UnknownHostException{
this.client = new ClientBean(clientport, serverport, serveraddr, localaddr);;
}
public ClientBean getClient() {
return client;
}
public void setClient(ClientBean client) {
this.client = client;
}
public void SendMessage() throws IOException{
client.sendToServer();
}
public void bind() throws SocketException, UnknownHostException{
client.bind();
}
public void setContent(String content){
client.setContent(content);
}
public void run() {
try {
SendMessage();
}catch (IOException e) {
e.printStackTrace();
}
}
}
public class UDPClient{
public static int clientport;
public static int serverport;
public static String content;
static byte[] ip;
static InetAddress serveraddr;
static InetAddress localaddr;
static BufferedReader input;
static ClientBeanThread client;
public static void main(String args[]) throws IOException, InterruptedException
{
clientport = 1985;
serverport = 1986;
ip = new byte[] { (byte) 192, (byte) 168, (byte) 30, (byte) 13 };
serveraddr = InetAddress.getByAddress(ip);
localaddr = InetAddress.getLocalHost();
input = new BufferedReader(new InputStreamReader(System.in));
client = new ClientBeanThread(clientport, serverport, serveraddr, localaddr);
client.bind();
System.out.println("客户端启动");
System.out.print("Server Address: ");
//获取套接字连接的地址
System.out.print("HostName " + client.getClient().getServeraddr().getHostName());
System.out.print(" Address " + client.getClient().getServeraddr().getHostAddress());
System.out.print(" Port " + client.getClient().getServerport() + "\n");
System.out.print("Local Address: ");
//获取套接字绑定的本地地址
System.out.print("HostName " + client.getClient().getDs().getLocalAddress().getHostName());
System.out.print(" Address " + client.getClient().getDs().getLocalAddress().getHostAddress());
System.out.print(" port " + client.getClient().getDs().getLocalPort() + "\n");
System.out.println("请输入发送内容,回车发送,键入end时发送结束");
while(true){
content = input.readLine();
client.setContent(content);
new Thread(client).start();
if (content.equalsIgnoreCase("end")){
System.out.println("Send is over.");
break;
}
}
Thread.sleep(2000);
System.out.println("Socket has closed.");
client.getClient().getDs().disconnect();
client.getClient().getDs().close();
}
}
测试运行:
客户端
客户端启动
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
Send is over.
Socket has closed.
服务器端
服务器端启动,绑定端口 1986
Message Recevied:
nihao
Message From /192.168.30.13:1985
this is a udp test
Message From /192.168.30.13:1985
end
Message From /192.168.30.13:1985
The Message is over, client socket has closed.