プライベートな連絡先の最初の情報
送料メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
ソケット API はすべてシステムによって提供されます。システムごとに提供される API は異なりますが、これらのシステム API はさらに Java でカプセル化されます。
UDP のソケット API は、DatagramSocket と DatagramPacket の 2 つのクラスに焦点を当てています。
このクラスの機能は、「ネットワークカードの操作」、つまりネットワークカードの読み書き操作を行うためのリモコンと考えることができ、ファイルの読み書きと同様に理解できます。
いくつかのメソッドが提供されています。
このクラスは、UDP データグラムを記述します。DatagramPacket オブジェクトは、一度送受信されると送信されます。
エコー: クライアントはさまざまなリクエストをサーバーに送信し、サーバーはさまざまな応答を返します。ただし、ここでのエコーはクライアントがサーバーに要求したものであり、サーバーは計算やビジネス ロジックなしで応答します。
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();
}
}
DatagramPacket オブジェクトはデータグラムを表します。UDP データグラムはヘッダーとペイロードで構成されます。ヘッダー内の IP アドレスとポート番号は DatagramPacket クラスの属性ですが、ペイロード クラスは提供されないため、プログラマが行う必要があります。僧侶が托鉢するのと同じように、托鉢を用意し、各家族がその中に食べ物を入れます。データグラムの本質はバイナリデータであるため、ペイロードとしてバイト配列を提供しました。 . データの保存。
クライアントから受信したデータはサーバーで処理された後にクライアントに返される必要があるため、サーバーで処理されたデータを格納する DatagramPacket オブジェクトを作成し、サーバーがそれをクライアントに送信する必要があります。このとき、DatagramPacket オブジェクトには空白を設ける必要はなく、データ受信時にクライアントの IP アドレスとポート番号が記録されるため、このオブジェクトに処理済みのデータを入れます。クライアントに送信するときに記録されます。 requestPacket.getSocketAddress() を通じてクライアントの IP アドレスとポート番号を取得する必要があります。
サーバーは固定されているため、ポート番号はサーバーの起動時に作成されます。
ポート番号 IP アドレスが必要なのはなぜですか?
2 者間のコミュニケーションを成功させるには、次の 4 つの主要な指標が存在する必要があります。
送信元ポート、送信元IP、宛先ポート、宛先IP
これらの 4 つのコア インジケータを通じて、クライアントとサーバーが同じホスト上にあるため、ここではサーバーの IP アドレスはありません。ループバック IP とも呼ばれる 172.0.0.1 を表す IP を使用できます。
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();
}
}
requestPacket オブジェクトは、コンソールから受信した文字列について、文字列オブジェクトの参照と長さ、さらに独自の IP と Prot を取得し、ソケットの send メソッドを通じてサーバーに送信します。
サーバーからのレスポンスを受け取るには、responsePacktオブジェクトを作成し、サーバーからのレスポンスを受け取るための空のバイト配列を事前に作成しておく必要があります。
いくつかのメソッドを区別します。
メソッドを区別する前に、バイト、文字、エンコード形式の概念を理解する必要があります。
コンピュータは 0101 のみを認識するため、バイトと文字は基本的に 2 進数 (0101 のようなデータ) です。
バイト: バイトは、コンピュータがデータを保存するための基本単位です。1 バイトは 8 ビットであり、1 バイトが 256 個の異なる値を表すことができます。
文字: 文字は、テキスト情報を表す基本単位です。エンコード形式に応じて、文字に対応するバイト数が異なり、文字をバイトに変換してデータを表現できます。データとストアデータ。
エンコード形式:
方法は異なります。
ここで、継承とポリモーフィズムの考え方を適用してこのサーバーを実装できます。この辞書翻訳サーバーとエコー サーバーの本質的な違いは応答の処理であるため、繰り返しコードを継承して再利用し、必要なコードを拡張できます。
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();
}
}
この辞書変換を実装するには、データ構造内にマップも必要であり、マップ内のキーと値のペアを使用してデータを保存します。
そうすれば、特定の業務操作は、プロセス メソッドを書き換えるだけで済みます。
ここで実行する場合、親クラスのudpEchoServerオブジェクトを参照していますが、udpDictServerサブクラスは親クラスのudpEchoServerを継承してprocessメソッドをオーバーライドしているため、ポリモーフィック機能により実行されるprocessメソッドは実際にはサブクラスメソッドのプロセスとなります。