Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Todas las API de Socket son proporcionadas por el sistema. Las API proporcionadas por diferentes sistemas son diferentes, pero estas API del sistema están encapsuladas aún más en Java.
La API de socket en UDP se centra en dos clases: DatagramSocket y DatagramPacket
La función de esta clase puede considerarse como un control remoto para "operar la tarjeta de red", es decir, operaciones de lectura y escritura en la tarjeta de red, que puede entenderse como leer y escribir archivos similares.
Se proporcionan varios métodos:
Esta clase describe datagramas UDP. Un objeto DatagramPacket es equivalente a un datagrama UDP. Una vez enviado y recibido, se transmite un objeto DatagramPacket.
Eco: el cliente envía diferentes solicitudes al servidor y el servidor devuelve diferentes respuestas. Pero el eco aquí es lo que el cliente solicita al servidor, y el servidor responde sin ningún cálculo o lógica empresarial.
public class udpEchoServer {
public DatagramSocket socket = null;
public udpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动!!!");
while (true) {
//接受客户端请求
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
//为了更好处理数据并方便打印,将接受的数据转化为字符串操作
String request = new String(requestPacket.getData(),0,requestPacket.getLength());
//处理客户端的请求(算术计算或者业务逻辑)
String response = this.process(request);
//将处理完的请求返还给客户端
DatagramPacket resposePacket = new DatagramPacket(response.getBytes(),0,response.getBytes().length,
requestPacket.getSocketAddress());
socket.send(resposePacket);
//打印客户端的ip地址端口号和接收客户端的数据以及处理完客户端后的数据
System.out.printf("[%s:%d] req = %s,resp = %sn",requestPacket.getAddress(),requestPacket.getPort(),
request,response);
}
}
public String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
udpEchoServer udpEchoServer = new udpEchoServer(9999);
udpEchoServer.start();
}
}
El objeto DatagramPacket representa un datagrama. Un datagrama UDP se compone de un encabezado y una carga útil. La dirección IP y el número de puerto en el encabezado son atributos de la clase DatagramPacket, pero no se proporciona la clase de carga útil, por lo que el programador debe hacerlo. Él mismo siempre, así como un monje que pide limosna, debe proporcionar un cuenco para la limosna y luego cada familia pone comida en el cuenco. Dado que la esencia del datagrama son datos binarios, proporcioné una matriz de bytes como carga útil. . Almacenamiento de datos.
Los datos recibidos del cliente deben devolverse al cliente después de ser procesados por el servidor, por lo que se debe crear un objeto DatagramPacket para almacenar los datos procesados por el servidor y luego el servidor los envía al cliente. En este momento, el objeto DatagramPacket no necesita proporcionar un espacio en blanco. Simplemente coloque los datos procesados en este objeto. Dado que la dirección IP y el número de puerto del cliente se registran al recibir los datos, solo la dirección IP y el número de puerto del cliente. se registran al enviarlo al cliente. Debe obtener la dirección IP y el número de puerto del cliente a través de requestPacket.getSocketAddress().
Dado que el servidor es fijo, usted mismo puede configurar directamente el número de puerto. El número de puerto se crea cuando se inicia el servidor.
¿Por qué necesito una dirección IP de número de puerto?
Para lograr una comunicación exitosa entre las dos partes, estos cuatro indicadores centrales deben estar presentes:
Puerto de origen, IP de origen, puerto de destino, IP de destino
A través de estos cuatro indicadores centrales, se puede lograr la comunicación de red entre las dos partes. Aquí no hay una dirección IP del servidor porque el cliente y el servidor están en el mismo host. Podemos usar una IP para representar 172.0.0.1, también conocida como IP de loopback.
public class udpEchoClient {
private DatagramSocket socket = null;
private String serverIp;
private int serverProt;
public udpEchoClient(String serverIp, int serverProt) throws SocketException {
socket = new DatagramSocket();
this.serverIp = serverIp;
this.serverProt = serverProt;
}
public void start() throws IOException {
System.out.println("客户端启动!");
//1.从控制台获取字符串
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println("请输入要发送的请求: ");
String request = scanner.nextLine();
//2.将输入的字符串发送给服务器,还要将发送的目标确定,IP和端口号
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), 0, request.getBytes().length,
InetAddress.getByName(serverIp), serverProt);
socket.send(requestPacket);
//3.从服务器读取到经过处理的响应
DatagramPacket responsePackt = new DatagramPacket(new byte[4096], 4096);
socket.receive(responsePackt);
//将响应打印在控制台
String response = new String(responsePackt.getData(), 0, responsePackt.getLength());
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
udpEchoClient udpEchoClient = new udpEchoClient("127.0.0.1",9999);
udpEchoClient.start();
}
}
Para la cadena recibida de la consola, el objeto requestPacket obtiene la referencia y la longitud del objeto de cadena, así como su propia IP y Prot, y luego lo envía al servidor a través del método de envío del socket.
Para recibir una respuesta del servidor, debe crear un objeto ResponsePackt y crear una matriz de bytes en blanco por adelantado para recibir la respuesta del servidor.
Distinguir algunos métodos:
Antes de distinguir métodos, debemos comprender los conceptos de bytes, caracteres y formas de codificación.
Los bytes y caracteres son esencialmente binarios, que son datos como 0101, porque la computadora solo reconoce 0101.
Byte: El byte es la unidad básica para el almacenamiento de datos en una computadora. 1 byte son 8 bits. Cada bit puede ser 0 o 1, lo que significa que un byte puede representar 256 valores diferentes.
Carácter: el carácter es la unidad básica para representar información de texto. Según las diferentes formas de codificación, el número de bytes correspondientes a un carácter varía. A través del formulario de codificación, los caracteres se pueden convertir en bytes y luego los bytes se pueden usar para representar datos. datos y almacenar datos.
Forma de codificación:
Los métodos son diferentes:
Aquí podemos aplicar las ideas de herencia y polimorfismo para implementar este servidor, porque la diferencia esencial entre este servidor de traducción de diccionario y el servidor de eco es el procesamiento de respuestas, por lo que podemos heredar y reutilizar el código repetido y expandir el código requerido.
public class udpDictServer extends udpEchoServer{
HashMap<String,String> map = null;
public udpDictServer(int port) throws SocketException {
super(port);
map = new HashMap<>();
map.put("server","服务");
map.put("client","客户端");
map.put("cat","🐱");
map.put("dog","🐕");
map.put("pig","🐖");
}
@Override
public String process(String request) {
return map.getOrDefault(request, "该词汇没有查询到");
}
public static void main(String[] args) throws IOException {
udpDictServer udpDictServer = new udpDictServer(9999);
udpDictServer.start();
}
}
Para implementar esta traducción de diccionario, también necesita un mapa en la estructura de datos y utilizar pares clave-valor en el mapa para almacenar datos.
Entonces, las operaciones comerciales específicas solo necesitan reescribir el método del proceso.
Al ejecutar aquí, aunque esto se refiere al objeto udpEchoServer de la clase principal, debido a que la subclase udpDictServer hereda la clase principal udpEchoServer y anula el método de proceso, el método de proceso ejecutado debido a la característica polimórfica es en realidad el proceso de la subclase.