这一篇文章我们将讲述网络编程中UDP服务器客户端的编程代码
1、前置知识
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。
UDP的特点有:无连接、尽最大努力交付、面向报文、没有拥塞控制
本文讲的回响服务器是指客户端向服务器发送一个报文,从服务器那里得到一条一模一样的回响报文
该代码需要在同一个包下创建两个类,服务器UdpEchoServer类,客户端UdpEchoClient类
2、服务器端代码
(1)完整代码
先放上完整代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
public class UdpEchoServer {
public static DatagramSocket socket = null;
public UdpEchoServer(int port) throws SocketException {
//手动指定服务器端口号
socket = new DatagramSocket(port);
}
public static void start() throws IOException {
while (true){
System.out.println("服务器启动");
DatagramPacket requestPacket = new DatagramPacket(new byte[1024],1024);
socket.receive(requestPacket);
String request = new String(requestPacket.getData(),0,requestPacket.getLength());
String response = process(request);
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
socket.send(responsePacket);
System.out.printf("[%s:%d] req:%s,resp:%s",requestPacket.getAddress(),requestPacket.getPort(),request,response);
System.out.println();
}
}
public static String process(String request){
return request;
}
public static void main(String[] args) throws IOException {
UdpServer server = new UdpServer(9090);
server.start();
}
}
(2)代码讲解
构造方法中手动指定服务器端口号
public UdpEchoServer(int port) throws SocketException {
//手动指定服务器端口号
socket = new DatagramSocket(port);
}
start()方法中进行信息的接收、处理、发送
public static void start() throws IOException {
while (true){
System.out.println("服务器启动");
//创建接收报文,用socket进行接收请求报文
DatagramPacket requestPacket = new DatagramPacket(new byte[1024],1024);
socket.receive(requestPacket);
//将请求报文转化为请求字符串,用process()方法进行处理,得到响应字符串
String request = new String(requestPacket.getData(),0,requestPacket.getLength());
String response = process(request);
//将得到的响应字符串转化为响应报文,并用socket进行发送
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
socket.send(responsePacket);
//打印客户端IP地址和端口号信息
System.out.printf("[%s:%d] req:%s,resp:%s",requestPacket.getAddress(),requestPacket.getPort(),request,response);
System.out.println();
}
}
process()方法
直接返回接收到的字符串
public static String process(String request){
return request;
}
3、 客户端代码
(1)完整代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
public static DatagramSocket socket = null;
private static String ip = null;
private static int port = 0;
public UdpEchoClient(String ip,int port) throws SocketException {
//系统自动为客户端分配端口
socket = new DatagramSocket();
this.ip = ip;
this.port = port;
}
public static void start() throws IOException {
System.out.println("客户端启动!");
Scanner scanner = new Scanner(System.in);
while (true){
System.out.print("->");
String request = scanner.next();
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(ip),port);
socket.send(requestPacket);
DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
socket.receive(responsePacket);
String response = new String(responsePacket.getData(),0,responsePacket.getLength());
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
(2)代码讲解
客户端由于可能有多个,所以需要系统自动为客户端分配端口
当初始化socket时,客户端还需要记下服务器端的ip和端口
public static DatagramSocket socket = null;
private static String ip = null;
private static int port = 0;
public UdpEchoClient(String ip,int port) throws SocketException {
//系统自动为客户端分配端口
socket = new DatagramSocket();
//记录ip和端口号
this.ip = ip;
this.port = port;
}
start()方法
public static void start() throws IOException {
System.out.println("客户端启动!");
Scanner scanner = new Scanner(System.in);
while (true){
System.out.print("->");
String request = scanner.next();
//将读取到的字符串转化为请求报文,并用socket进行发送
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(ip),port);
socket.send(requestPacket);
//创建回应报文来接收响应
DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
socket.receive(responsePacket);
//将响应报文转换成字符串,并打印出来
String response = new String(responsePacket.getData(),0,responsePacket.getLength());
System.out.println(response);
}
}