UDP
日本語 | 使用者情報形式規約 |
英語 | User Datagram Protocol |
ふりがな | ゆーでぃーぴー |
フリガナ | ユーディーピー |
コンピューター間の通信方法のひとつ。
コンピューター間の通信方法には、主に「TCP」と「UDP」がある。
UDPはTCPに比べて「低レベル」の通信を行う。
TCPが「文字列による確実な対話」を行うのに対して、UDPは「バイナリー形式の雑な送受信」を行う。
そのため、確実な通信向けではなく、ネットワークゲームのように「データが抜け落ちてもいいから早くて融通の利く通信を行いたい」場合によく使用される。
TCPとUDPは競合しないため、ポート番号が重なっても構わない。
そもそも、UDPには、TCPにおける、HTTP等のいわゆる「プロトコル」が存在しないため、ポート番号についてはそれほど神経質になる必要はないだろう。
JavaではDatagramSocketクラスを用いてUDPによる通信を行う。
通常のソケットとは方法が異なる点に注意。
UDPでは「パケット」というバイナリーデータの送受信を行うため、byte型配列とDatagramPacketクラスを用いて、送信用データ及び受信用データの受け皿を用意する。
コンピューター間の通信方法には、主に「TCP」と「UDP」がある。
UDPはTCPに比べて「低レベル」の通信を行う。
TCPが「文字列による確実な対話」を行うのに対して、UDPは「バイナリー形式の雑な送受信」を行う。
そのため、確実な通信向けではなく、ネットワークゲームのように「データが抜け落ちてもいいから早くて融通の利く通信を行いたい」場合によく使用される。
TCPとUDPは競合しないため、ポート番号が重なっても構わない。
そもそも、UDPには、TCPにおける、HTTP等のいわゆる「プロトコル」が存在しないため、ポート番号についてはそれほど神経質になる必要はないだろう。
JavaではDatagramSocketクラスを用いてUDPによる通信を行う。
通常のソケットとは方法が異なる点に注意。
UDPでは「パケット」というバイナリーデータの送受信を行うため、byte型配列とDatagramPacketクラスを用いて、送信用データ及び受信用データの受け皿を用意する。
// Sample.java
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
// ポート番号12345で通信します。
// ……もし、ポート番号12345が空いてないとダメです。
// その場合はこの数字を他のにしてください。
final int PORT = 12345;
// 対象のホスト名。自分自身なのでlocalhostです。
final String HOST = "localhost";
// サーバーは別スレッドで。
// もちろん、普通は「別のプログラム」をサーバーにします。
ServerThread thread = new ServerThread( PORT );
thread.start();
try
{
// このスレッドを3秒止めます。
// サーバー側の準備ができるのを待つためです。
Thread.sleep( 3 * 1000 );
}
catch( InterruptedException e )
{
// sleep()メソッドを呼んでいる間に割り込みが入ると
// InterruptedException例外が投げられます。
e.printStackTrace();
}
// 以下、クライアント側の処理。
// finallyでclose()するためここで宣言します。
DatagramSocket datagramSocket = null;
try
{
// localhostを示すInetAddressクラスです。
InetAddress inetAddress = InetAddress.getByName( HOST );
// UDPで接続するためのDatagramSocketクラスを作ります。
// ポート番号等は指定しません。
datagramSocket = new DatagramSocket();
// 送信用文字列です。
// UDPなので、byte型の配列にします。
String string = "あいうえお";
byte[] bytes = string.getBytes();
// データを送信するためのDatagramPacketクラスを用意します。
// ここで送信先ホスト名やポート番号を指定します。
DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length, inetAddress, PORT );
// 文字列をサーバー側に出力します。
System.out.println( "[クライアント]「あいうえお」を出力します。" );
datagramSocket.send( datagramPacket );
System.out.println( "[クライアント]「あいうえお」を出力しました。" );
// [サーバー]待機開始!
// [クライアント]「あいうえお」を出力します。
// [サーバー]待機終了。
// [サーバー]出力開始。
// [クライアント]「あいうえお」を出力しました。
// あいうえお
// [サーバー]出力完了。
}
catch( UnknownHostException e )
{
// InetAddressクラスのgetByName()メソッドを呼び出して、
// ホストからIPアドレスを取得できない場合は
// UnknownHostException例外が投げられます。
e.printStackTrace();
}
catch( IOException e )
{
// 出力時に問題があったらIOException例外が投げられます。
e.printStackTrace();
}
finally
{
if( datagramSocket != null )
{
// ソケットを閉じます。
datagramSocket.close();
}
}
}
}
/**
* サーバー側。
*/
class ServerThread extends Thread
{
/** ポート番号 */
private int port;
/**
* コンストラクタ。
*/
public ServerThread( int port )
{
this.port = port;
}
/**
* サーバーを起動します。
*/
public void run()
{
// finallyでclose()するためここで宣言します。
DatagramSocket datagramSocket = null;
try
{
// データを受け取るためのDatagramPacketクラスを用意します。
byte[] bytes = new byte[256];
DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length );
// ポート番号を指定して、UDPサーバーを作ります。
datagramSocket = new DatagramSocket( port );
// クライアントからのアクセスを待機開始!
System.out.println( "[サーバー]待機開始!" );
datagramSocket.receive( datagramPacket );
System.out.println( "[サーバー]待機終了。" );
// 受け取った文字列を出力します。
// 受け取った文字列はbyte型配列に入れられています。
// ただし、実際に受信したバイト数はDatagramPacketクラスの
// getLength()メソッドで取得します。
System.out.println( "[サーバー]出力開始。" );
String string = new String( bytes, 0, datagramPacket.getLength() );
System.out.println( string );
System.out.println( "[サーバー]出力完了。" );
}
catch( IOException e )
{
// 出力時に問題があったらIOException例外が投げられます。
e.printStackTrace();
}
finally
{
if( datagramSocket != null )
{
datagramSocket.close();
}
}
}
}
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
// ポート番号12345で通信します。
// ……もし、ポート番号12345が空いてないとダメです。
// その場合はこの数字を他のにしてください。
final int PORT = 12345;
// 対象のホスト名。自分自身なのでlocalhostです。
final String HOST = "localhost";
// サーバーは別スレッドで。
// もちろん、普通は「別のプログラム」をサーバーにします。
ServerThread thread = new ServerThread( PORT );
thread.start();
try
{
// このスレッドを3秒止めます。
// サーバー側の準備ができるのを待つためです。
Thread.sleep( 3 * 1000 );
}
catch( InterruptedException e )
{
// sleep()メソッドを呼んでいる間に割り込みが入ると
// InterruptedException例外が投げられます。
e.printStackTrace();
}
// 以下、クライアント側の処理。
// finallyでclose()するためここで宣言します。
DatagramSocket datagramSocket = null;
try
{
// localhostを示すInetAddressクラスです。
InetAddress inetAddress = InetAddress.getByName( HOST );
// UDPで接続するためのDatagramSocketクラスを作ります。
// ポート番号等は指定しません。
datagramSocket = new DatagramSocket();
// 送信用文字列です。
// UDPなので、byte型の配列にします。
String string = "あいうえお";
byte[] bytes = string.getBytes();
// データを送信するためのDatagramPacketクラスを用意します。
// ここで送信先ホスト名やポート番号を指定します。
DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length, inetAddress, PORT );
// 文字列をサーバー側に出力します。
System.out.println( "[クライアント]「あいうえお」を出力します。" );
datagramSocket.send( datagramPacket );
System.out.println( "[クライアント]「あいうえお」を出力しました。" );
// [サーバー]待機開始!
// [クライアント]「あいうえお」を出力します。
// [サーバー]待機終了。
// [サーバー]出力開始。
// [クライアント]「あいうえお」を出力しました。
// あいうえお
// [サーバー]出力完了。
}
catch( UnknownHostException e )
{
// InetAddressクラスのgetByName()メソッドを呼び出して、
// ホストからIPアドレスを取得できない場合は
// UnknownHostException例外が投げられます。
e.printStackTrace();
}
catch( IOException e )
{
// 出力時に問題があったらIOException例外が投げられます。
e.printStackTrace();
}
finally
{
if( datagramSocket != null )
{
// ソケットを閉じます。
datagramSocket.close();
}
}
}
}
/**
* サーバー側。
*/
class ServerThread extends Thread
{
/** ポート番号 */
private int port;
/**
* コンストラクタ。
*/
public ServerThread( int port )
{
this.port = port;
}
/**
* サーバーを起動します。
*/
public void run()
{
// finallyでclose()するためここで宣言します。
DatagramSocket datagramSocket = null;
try
{
// データを受け取るためのDatagramPacketクラスを用意します。
byte[] bytes = new byte[256];
DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length );
// ポート番号を指定して、UDPサーバーを作ります。
datagramSocket = new DatagramSocket( port );
// クライアントからのアクセスを待機開始!
System.out.println( "[サーバー]待機開始!" );
datagramSocket.receive( datagramPacket );
System.out.println( "[サーバー]待機終了。" );
// 受け取った文字列を出力します。
// 受け取った文字列はbyte型配列に入れられています。
// ただし、実際に受信したバイト数はDatagramPacketクラスの
// getLength()メソッドで取得します。
System.out.println( "[サーバー]出力開始。" );
String string = new String( bytes, 0, datagramPacket.getLength() );
System.out.println( string );
System.out.println( "[サーバー]出力完了。" );
}
catch( IOException e )
{
// 出力時に問題があったらIOException例外が投げられます。
e.printStackTrace();
}
finally
{
if( datagramSocket != null )
{
datagramSocket.close();
}
}
}
}
// Sample.java import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.UnknownHostException; import java.io.IOException; public class Sample { public static void main( String[] args ) { // ポート番号12345で通信します。 // ……もし、ポート番号12345が空いてないとダメです。 // その場合はこの数字を他のにしてください。 final int PORT = 12345; // 対象のホスト名。自分自身なのでlocalhostです。 final String HOST = "localhost"; // サーバーは別スレッドで。 // もちろん、普通は「別のプログラム」をサーバーにします。 ServerThread thread = new ServerThread( PORT ); thread.start(); try { // このスレッドを3秒止めます。 // サーバー側の準備ができるのを待つためです。 Thread.sleep( 3 * 1000 ); } catch( InterruptedException e ) { // sleep()メソッドを呼んでいる間に割り込みが入ると // InterruptedException例外が投げられます。 e.printStackTrace(); } // 以下、クライアント側の処理。 // finallyでclose()するためここで宣言します。 DatagramSocket datagramSocket = null; try { // localhostを示すInetAddressクラスです。 InetAddress inetAddress = InetAddress.getByName( HOST ); // UDPで接続するためのDatagramSocketクラスを作ります。 // ポート番号等は指定しません。 datagramSocket = new DatagramSocket(); // 送信用文字列です。 // UDPなので、byte型の配列にします。 String string = "あいうえお"; byte[] bytes = string.getBytes(); // データを送信するためのDatagramPacketクラスを用意します。 // ここで送信先ホスト名やポート番号を指定します。 DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length, inetAddress, PORT ); // 文字列をサーバー側に出力します。 System.out.println( "[クライアント]「あいうえお」を出力します。" ); datagramSocket.send( datagramPacket ); System.out.println( "[クライアント]「あいうえお」を出力しました。" ); // [サーバー]待機開始! // [クライアント]「あいうえお」を出力します。 // [サーバー]待機終了。 // [サーバー]出力開始。 // [クライアント]「あいうえお」を出力しました。 // あいうえお // [サーバー]出力完了。 } catch( UnknownHostException e ) { // InetAddressクラスのgetByName()メソッドを呼び出して、 // ホストからIPアドレスを取得できない場合は // UnknownHostException例外が投げられます。 e.printStackTrace(); } catch( IOException e ) { // 出力時に問題があったらIOException例外が投げられます。 e.printStackTrace(); } finally { if( datagramSocket != null ) { // ソケットを閉じます。 datagramSocket.close(); } } } } /** * サーバー側。 */ class ServerThread extends Thread { /** ポート番号 */ private int port; /** * コンストラクタ。 */ public ServerThread( int port ) { this.port = port; } /** * サーバーを起動します。 */ public void run() { // finallyでclose()するためここで宣言します。 DatagramSocket datagramSocket = null; try { // データを受け取るためのDatagramPacketクラスを用意します。 byte[] bytes = new byte[256]; DatagramPacket datagramPacket = new DatagramPacket( bytes, bytes.length ); // ポート番号を指定して、UDPサーバーを作ります。 datagramSocket = new DatagramSocket( port ); // クライアントからのアクセスを待機開始! System.out.println( "[サーバー]待機開始!" ); datagramSocket.receive( datagramPacket ); System.out.println( "[サーバー]待機終了。" ); // 受け取った文字列を出力します。 // 受け取った文字列はbyte型配列に入れられています。 // ただし、実際に受信したバイト数はDatagramPacketクラスの // getLength()メソッドで取得します。 System.out.println( "[サーバー]出力開始。" ); String string = new String( bytes, 0, datagramPacket.getLength() ); System.out.println( string ); System.out.println( "[サーバー]出力完了。" ); } catch( IOException e ) { // 出力時に問題があったらIOException例外が投げられます。 e.printStackTrace(); } finally { if( datagramSocket != null ) { datagramSocket.close(); } } } }