1 UDP通信メカニズム
インターネット プロトコル スイートは、ユーザー データグラム プロトコル ( UDP ) と呼ばれるコネクションレス型トランスポート プロトコルをサポートしています。TCP プロトコルとは異なり、UDP は、アプリケーションが接続を確立せずにカプセル化された IP パケットを送信する方法を提供します。データを送信する前に、(DatagramSocket クラスを使用して) データを送受信するためのパケット操作 (DatagramPacket クラスを使用) を実行する必要があります。
UDP を使用してデータを送信する場合、次のような問題が発生する可能性があります。
荷物の紛失。
故障中;
エラーパケット。
データパケットの繰り返し送信。
通常、UDP の使用が必要となるシナリオは、主に、ビデオ ストリーミング、オーディオ ストリーミングなど、データ フローの要件が高くない場合です。
2 UDP 通信プログラミングの一般的な手順
-
クライアントの DatagramSocket を作成し、クライアントがメッセージを受信するために使用するポートを定義します。
-
サーバー側で DatagramSocket を作成し、サーバーがメッセージを受信するために使用するポートを定義します。
-
サーバー側で DatagramPacket オブジェクトを作成し、送信されるデータ パケットをカプセル化します。
-
クライアントがメッセージを送信します。
-
サーバーはメッセージを受信します。
3サーバー
サーバーはDatagramSocket
データを受信するためにオブジェクトを使用します。オブジェクトを作成するときに、リクエストを受信するためのポートを指定する必要があります。
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpServer {
public static void main(String[] args) {
try {
//创建服务端接收数据的 DatagramSocket 对象
DatagramSocket datagramSocket = new DatagramSocket(5555);
//创建数据缓冲区
byte[] buff = new byte[1024];
//创建数据报的包对象
DatagramPacket packet = new DatagramPacket(buff, buff.length);
//等待接收客户端发送的数据
datagramSocket.receive(packet);
//获取数据
String input = new String(packet.getData(), 0, packet.getLength());
System.out.println("接收到客户端的请求: " + input);
} catch (Exception e) {
e.printStackTrace();
}
}
}
クライアントからリクエストを受信するときは、一度に 1024 バイトのデータを受信できるバイト バッファーが使用されるため、ネットワーク IO 操作が削減されます。
サーバーとクライアント間のデータ フローではDatagramPacket
カプセル化が使用されるため、データを受信する場合は、このオブジェクトを使用して受信する必要があります。
datagramSocket.receive(packet);
メソッドはブロッキングメソッドとなっており、データを受信しない場合はここで待機し、データ受信後は引き続き以下のコードを実行します。
バイトデータを受け取った後、バイナリデータをそのまま使用したくない場合は、データを変換する必要があります。
new String(packet.getData(), 0, packet.getLength())
ネットワーク カードから読み取られた実際のデータがバッファの長さよりも短い場合、データはサーバーで利用できないため、受信データを取得するときにバッファの内容がすべて読み取られるわけではありません。実際に受信したデータグラムを取得するだけで済みます。
クライアント4名
クライアントを作成するときは、DatagramSocket オブジェクトを作成し、データ送信用のポートを指定する必要もあります。クライアントがサーバーと同じマシン上にある場合、ポートはサーバーとは異なる必要があります。
クライアントがデータを送信するときは、データを DatagramPacket オブジェクトにカプセル化する必要があり、データを受信するためのサーバー IP とポートを指定する必要があります。
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;
public class UdpClient {
public static void main(String[] args) {
try {
//创建数据发送对象,并指定要发送数据的端口
DatagramSocket socket = new DatagramSocket(5556);
//将要发送的数据转换为字节数组
Scanner scanner = new Scanner(System.in);
String output = scanner.next();
byte[] bytes = output.getBytes();
//创建数据报的包对象
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, new InetSocketAddress("127.0.0.1", 5555));
//发送消息
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5 通信
5.1 サーバーを起動しないでください
サーバーが起動されておらず、クライアントのみがデータ送信を開始した場合、クライアントはエラーを報告せずに正常にデータを送信します。
クライアントがデータ送信時にサーバーをチェックしなかったことがわかります。
5.2 サーバーの起動
これは1つの通信ですが、複数の通信を確立したい場合は、TCP通信と同様にサーバー側でループを追加します。