2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Les API Socket sont toutes fournies par le système. Les API fournies par différents systèmes sont différentes, mais ces API système sont encapsulées en Java.
L'API socket dans UDP se concentre sur deux classes : DatagramSocket et DatagramPacket.
La fonction de cette classe peut être considérée comme une télécommande pour « faire fonctionner la carte réseau », c'est-à-dire des opérations de lecture et d'écriture sur la carte réseau, qui peuvent être comprises comme une lecture et une écriture comme des fichiers.
Plusieurs méthodes sont proposées :
Cette classe décrit les datagrammes UDP. Un objet DatagramPacket est équivalent à un datagramme UDP. Une fois envoyé et reçu une fois, un objet DatagramPacket est transmis.
Echo : le client envoie différentes requêtes au serveur et le serveur renvoie différentes réponses. Mais l'écho ici est ce que le client demande au serveur, et le serveur répond sans aucun calcul ni logique métier.
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();
}
}
L'objet DatagramPacket représente un datagramme. Un datagramme UDP est composé d'un en-tête et d'une charge utile. L'adresse IP et le numéro de port dans l'en-tête sont des attributs de la classe DatagramPacket, mais la classe de charge utile n'est pas fournie, le programmeur doit donc le faire. Fourni, donc tout comme un moine demandant l'aumône, vous devez fournir un bol pour l'aumône, puis chaque famille met de la nourriture dans le bol. Puisque l'essence du datagramme est constituée de données binaires, je fournis un tableau d'octets comme charge utile. . Stocker des données.
Les données reçues du client doivent être renvoyées au client après avoir été traitées par le serveur, donc un objet DatagramPacket doit être créé pour stocker les données traitées par le serveur, puis le serveur les envoie au client. Pour le moment, l'objet DatagramPacket n'a pas besoin de fournir un espace vide. Mettez simplement les données traitées dans cet objet puisque l'adresse IP et le numéro de port du client sont enregistrés lors de la réception des données, seuls l'adresse IP et le numéro de port du client. sont enregistrés lors de son envoi au client. Vous devez obtenir l'adresse IP et le numéro de port du client via requestPacket.getSocketAddress().
Le serveur étant fixe, vous pouvez définir directement vous-même le numéro de port. Le numéro de port est créé au démarrage du serveur.
Pourquoi ai-je besoin d’une adresse IP de numéro de port ?
Pour parvenir à une communication réussie entre les deux parties, ces quatre indicateurs clés doivent être présents :
Port source, IP source, port de destination, IP de destination
Grâce à ces quatre indicateurs principaux, la communication réseau entre les deux parties peut être réalisée. Il n'y a pas d'adresse IP du serveur ici car le client et le serveur sont sur le même hôte. Nous pouvons utiliser une adresse IP pour représenter 172.0.0.1, également connue sous le nom d'adresse IP de bouclage.
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();
}
}
Pour la chaîne reçue de la console, l'objet requestPacket obtient la référence et la longueur de l'objet chaîne, ainsi que ses propres IP et Prot, puis l'envoie au serveur via la méthode d'envoi du socket.
Pour recevoir une réponse du serveur, vous devez créer un objet ResponsePackt et créer au préalable un tableau d'octets vide pour recevoir la réponse reçue du serveur.
Il existe quelques méthodes :
Avant de distinguer les méthodes, nous devons comprendre les concepts d'octets, de caractères et de formes d'encodage.
Les octets et les caractères sont essentiellement binaires, ce qui correspond à des données telles que 0101, car l'ordinateur ne reconnaît que 0101.
Octet : L'octet est l'unité de base pour le stockage informatique des données. 1 octet correspond à 8 bits. Chaque bit peut être 0 ou 1, ce qui signifie qu'un octet peut représenter 256 valeurs différentes.
Caractère : le caractère est l'unité de base pour représenter les informations textuelles. Selon les différentes formes de codage, le nombre d'octets correspondant à un caractère sera différent. Grâce à la forme de codage, les caractères peuvent être convertis en octets, puis les octets peuvent être utilisés pour représenter les données. . Transférer des données et stocker des données.
Forme d'encodage :
Les méthodes sont différentes :
Ici, nous pouvons appliquer les idées d'héritage et de polymorphisme pour implémenter ce serveur, car la différence essentielle entre ce serveur de traduction de dictionnaire et le serveur d'écho est le traitement des réponses, nous pouvons donc hériter et réutiliser le code répété et développer le code requis.
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();
}
}
Pour implémenter cette traduction de dictionnaire, vous avez également besoin d'une carte dans la structure de données et utilisez les paires clé-valeur de la carte pour stocker les données.
Il suffit ensuite de réécrire la méthode de processus pour des opérations commerciales spécifiques.
Lors de l'exécution ici, bien que cela fasse référence à l'objet udpEchoServer de la classe parent, étant donné que la sous-classe udpDictServer hérite de la classe parent udpEchoServer et remplace la méthode de processus, la méthode de processus exécutée en raison de la fonctionnalité polymorphe est en fait le processus de la méthode de sous-classe.