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();
}
}
}
}




