UDPの送受信プログラム例

コネクションレスで、相手が待機していなくても送信できます。
また、受信データが正しいかも判断できません。
その正当性は、アプリケーションプログラムにゆだねられています。

 

UDP送信プログラムです。

入力した1行をUDPで送信するプログラムで、空のキー入力するまで繰り返します。

import java.io.*;//BufferedReadered用
import java.net.*;//DatagramSocket、InetAddress用

public class UDPSndTest{
	static BufferedReader br = new BufferedReader( new InputStreamReader(System.in) );

	DatagramSocket sendSocket = new DatagramSocket();//UDP送信用ソケット
	InetAddress inetAddress = InetAddress.getByName("127.0.0.1");//送信先
	
	public UDPSndTest() throws Exception {//コンストラクタ
	}
	
	public boolean send() throws Exception {
		System.out.print("msg==>");
		String msg = br.readLine();//送信メッセージキー入力
		byte []buf = msg.getBytes();//バイト列に変換
		DatagramPacket packet= new DatagramPacket(buf,buf.length, inetAddress, 5431);//IPアドレス、ポート番号も指定
		sendSocket.send(packet);//送信
		if(msg.equals("")){
			return false;//入力文字列なしで終了
		}
		return true;
	}
		
	public static void main(String [] args) throws Exception{
		UDPSndTest test = new UDPSndTest();
		
		while(test.send() == true)//送信の繰り返し
			;
		test.sendSocket.close();
		System.out.print("Press Enter Key");
		br.readLine();
	}
}

DatagramSocketクラスのオブジェクトを作成し、 UDPパケットをカプセル化したDatagramPacketのオブジェクトを引数とするsendメソッドで送信しています。


 

UDP受信プログラム

前述の送信プログラムに対する受信プログラムです。
空のパケットを(受信データ部のサイズが0)受け取るまで、受信データを表示するだけのプログラムです

import java.io.*;//BufferedReadered用
import java.net.*;//DatagramSocket用

public class UDPRecTest{
	static BufferedReader br = new BufferedReader( new InputStreamReader(System.in) );

	DatagramSocket recSocket = new DatagramSocket(5431);//UDP受信用ソケット
	SocketAddress sockAddress;//接続してきた送信元
	
	public UDPRecTest() throws Exception {//コンストラクタ
	}
	
	public boolean receive() throws Exception {
		byte []buf = new byte[256];
		DatagramPacket packet= new DatagramPacket(buf,buf.length);
		recSocket.receive(packet);//受信 & wait
		sockAddress = packet.getSocketAddress(); //送信元情報取得
		
		int len = packet.getLength();//受信バイト数取得
		String msg = new String(buf, 0, len);
		if(msg.equals("")){
			return false;//入力文字列なしで終了
		}
		System.out.println(msg + ":" + len + "byte receive by "+ sockAddress.toString());
		return true;
	}
	public static void main(String [] args) throws Exception{
		UDPRecTest test = new UDPRecTest();
		
		while(test.receive() == true)//受信の繰り返し
			;
		
		System.out.print("Press Enter Key");
		br.readLine();
	}
}

TCPと違いUDPには再送制御がありません。
(受信したデータのチェックサムでエラーなら、そのパケットは破棄されるだけ)
つまり信頼性がより、負荷の軽い処理や連続性や要求されるアプリケーション向けのプロトコルです。

データの受け取り損なう確認ができるプログラムを検討しましょう。
それには、多量の情報を送信する必要があります。
以下に示すプログラムは、マウスでドラックしたところを線で結ぶプログラムです。
これを、UDP送信用と受信用に分けてみましょう。
一方でドラックした座標を描画とともに送信し、 他方では、受信した座標で描画するようにするわけです。

import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.*;//BufferedImage関連利用のため

//JFrameクラスのフレームがプログラムされている部分を継承したThreadTestFrameクラスの定義
public class ThreadTestFrame extends JFrame implements  MouseListener ,MouseMotionListener , Runnable{
	static BufferedReader br = new BufferedReader( new InputStreamReader(System.in) );
	
	BufferedImage img;	//描画イメージメモリ領域 (オフスクリーン)
	Graphics graphics;//描画情報管理
	int px, py;//線描画の始点
	Thread thread = new Thread(this);
	
    	//コンストラクタ
	public ThreadTestFrame(String title) throws Exception{
		super(title); //JFrameのコンストラクタ呼び出し
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//クローズボタンで終了させる指定

		this.setSize(400,400);//クライアント領域サイズ設定
		
		//描画イメージメモリ領域の初期化
		img= new BufferedImage(400,400,BufferedImage.TYPE_INT_RGB);///クライアントと同じサイズ
		graphics = img.createGraphics();//描画ツール取得
		graphics.setColor(new Color(255,255,255));//白
		graphics.fillRect(0,0,400, 400);// 矩形領域を塗りつぶし
		graphics.setColor(new Color(255,0,0));//赤
		
		this.getContentPane().addMouseListener(this);// クライアントでのマウス処理をこのクラスに任せる指示
		this.getContentPane().addMouseMotionListener(this);// クライアントでのマウス処理をこのクラスに任せる指示
		
		//this.run();
		this.thread.start();
	}

	// システムが描画を必要とした時に実行するpaintをオーバーライド(作り直す)	
	 public void paint(java.awt.Graphics g) {
		g = this.getContentPane().getGraphics();
		g.drawImage(this.img, 0, 0, this.getContentPane());//imgメモリをクライアントに描画
	}
	
	//MouseListenerインターフェイスの実装
	public void mouseClicked(MouseEvent e) { //コンポーネント上でマウスボタンをクリック (押してから離す) したときに呼び出されます。
	}	 
	public void mouseEntered(MouseEvent e) {//コンポーネントにマウスが入ると呼び出されます。
	}
	public void mouseExited(MouseEvent e) { //コンポーネントからマウスが出ると呼び出されます。 
	}
	public void mousePressed(MouseEvent e){  // コンポーネント上でマウスボタンを押すと呼び出されます。 
		this.px = e.getX();
		this.py = e.getY();
	}		
	public void mouseReleased(MouseEvent e){ // コンポーネント上でマウスボタンを離すと呼び出されます。 
	}
	//MouseMotionListenerインターフェイスの実装
	public void mouseDragged(MouseEvent e) {//コンポーネント上でマウスのボタンを押してドラッグすると呼び出されます。 
		graphics.drawLine(this.px, this.py,  e.getX(), e.getY());
		this.px = e.getX();
		this.py = e.getY();
		this.repaint();//再描画指示(paintが、システムによって呼び出される)
	}
	public void mouseMoved(MouseEvent e) {//コンポーネント上で、ボタンを押さずにマウスを移動すると呼び出されます。
	}
 
	//フレーム生成、表示
	public static void main(String []args) throws Exception{
		ThreadTestFrame frame = new ThreadTestFrame("スレッド、マウス操作、メモリイメージ描画の実験用フレーム");
		frame.show();//表示
	}
	
	// mainとは、別のスレッドで実行する。  
	public void run(){
		try{
			while(this.thread != null){			
				System.out.print(">>");
				String msg = br.readLine(); //入力待ち
				System.out.println(msg);
				Thread.sleep(10);// 10m秒
			}		
		}
		catch(Exception e){
			System.out.println(e.toString());
		}
	}
}

受信ではパケットが届くまで、待たされます。 すると、プログラムが動かなくなるので、受信する命令は別のスレッドで実行する必要があります
上記キー入力部のスレッド内で、キー入力の代わりに受信させるとよいでしょう。

答えの例
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送