UDP 接続オブジェクトの原理分析と使用例

UDP 接続オブジェクトの原理分析と使用例

以前、UDP を使い始めるために簡単な UDP サーバーとクライアントの例を作成しましたが、実際に使用してみると問題が発生しました。

前回使用したときも、接続オブジェクト DatagramSocket を static として記述し、クラスの初期化時に使用していました。しかし、システム内の多くの場所で使用されています。このクラスのオブジェクトを作成し続ける必要がありますか?

これを実行することは可能ですが、メモリ オーバーフローという結果を招く可能性があります。

UDP はステートレスです。DatagramSocket は、特定のアドレスのポートを指すために、毎回作成する必要はなく、一度作成するだけで済みます。

UDP はステートレスなので、DatagramSocket オブジェクトを作成すると、ネットワークを指すオブジェクトのみが作成されます。これは、特定の方向を向いた大きなスピーカーを設置しても、その方向で聞いている人がいるかどうかはわからないのと同じです。

サーバーが稼働していなくても、接続オブジェクトを作成してこのアドレスにデータを送信しても問題はありません。拡声器で特定の方向に向かって叫んでも、誰も聞いてくれなければ意味がありません。ただし、必要なときに応答が受信されない場合は、タイムアウト後にエラーが報告されます。

パッケージ udp; 
 
java.net.* をインポートします。 
 
/** 
 * @Description UDP クライアント プログラム。サーバーにデータを送信し、サーバーの応答情報を受信するために使用されます。* @author cuisuqiang 
 * @バージョン 1.0 
 * @since <a href="mailto:[email protected]" rel="external nofollow" >[email protected]</a> 
 */ 
パブリッククラス UdpClientSocket { 
  /** 
   * 接続オブジェクト */ 
  プライベート静的 DatagramSocket ds = null; 
  /** 
   * アドレスオブジェクト */ 
  プライベート静的SocketAddressアドレス = null; 
   
  /** 
   * クライアントのパケット送信方法と応答情報の受信方法をテストします*/ 
  パブリック静的void main(String[] args)は例外をスローします{ 
    初期化(); 
    while(true){ 
      UdpClientSocket.send(address,"こんにちは、親愛なる!".getBytes()); 
      UdpClientSocket を受信します。 
      試す { 
        スレッドをスリープ状態にします(3 * 1000); 
      } キャッチ (例外 e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
   
  /** 
   * 接続とアドレスを初期化します */ 
  パブリック静的void init(){ 
    試す { 
      ds = new DatagramSocket(8899); // クライアントとしてローカルポートにバインド ds.setSoTimeout(2 * 1000); 
      アドレス = 新しい InetSocketAddress("127.0.0.1",3344); 
    } キャッチ (例外 e) { 
      e.printStackTrace(); 
    } 
  } 
   
  /** 
   * 指定されたサーバーにデータ情報を送信します */ 
  パブリック静的void送信(SocketAddressアドレス、byte[]バイト){ 
    試す { 
      DatagramPacket dp = 新しい DatagramPacket(バイト、バイト長、アドレス); 
      ds.send(dp); 
    } キャッチ (例外 e) { 
      e.printStackTrace(); 
    } 
  } 
 
  /** 
   * 指定されたサーバーから送り返されたデータを受信します*/ 
  パブリック静的void受信(){ 
    試す { 
      byte[] buffer = 新しいbyte[1024]; 
      DatagramPacket dp = 新しい DatagramPacket(バッファ、バッファ長); 
      ds.receive(dp);    
      byte[]データ = new byte[dp.getLength()]; 
      System.arraycopy(dp.getData(), 0, データ, 0, dp.getLength());  
      System.out.println("サーバー応答データ: " + new String(data)); 
    } キャッチ (例外 e) { 
      e.printStackTrace(); 
    } 
  } 
}

コードを実行した結果は次のとおりです。

java.net.SocketTimeoutException: 受信がタイムアウトしました
java.net.PlainDatagramSocketImpl.receive0(ネイティブメソッド)
java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136) で
java.net.DatagramSocket.receive(DatagramSocket.java:712) で
udp.UdpClientSocket.receive(UdpClientSocket.java:69) で
udp.UdpClientSocket.main(UdpClientSocket.java:28) で

操作はタイムアウトしましたが、エラーはオブジェクトの作成とデータの送信によって発生したのではなく、データ受信時のタイムアウトによって発生しました。

このプログラムは実行し続けますので、サーバーを作成しましょう。

パッケージ udp;

java.net.DatagramPacket をインポートします。
java.net.DatagramSocket をインポートします。
java.net.InetSocketAddress をインポートします。
java.net.SocketAddress をインポートします。

/**
 * @UDP サービスクラスの説明 * @author cuisuqiang
 * @バージョン 1.0
 * @since [email protected]
 */
パブリッククラス UdpServerSocket {
	
	プライベート静的 DatagramSocket ds = null;
	プライベート静的SocketAddressアドレス = null;
	
	/**
	 * テスト方法 */
	パブリック静的void main(String[] args)は例外をスローします{
		初期化();
		System.out.println("---->サービスがリッスンを開始します!<----");
		(真)の間{
			UdpServerSocket.receive();
			UdpServerSocket.response(address,"こんにちは、食事はしましたか?");
		}		
	}
	
	パブリック静的void init(){
		試す {
			ds = 新しいデータグラムソケット(3344);
			ds.setSoTimeout(0);
			アドレス = 新しい InetSocketAddress("127.0.0.1",8899);
		} キャッチ (例外 e) {
			e.printStackTrace();
		}
	}

	/**
	 * データパケットを受信します。このメソッドはスレッドをブロックします */
	パブリック静的void受信() {
		試す {
			byte[] buffer = 新しいbyte[1024];
			DatagramPacket パケット = 新しい DatagramPacket(バッファ、バッファ長);
			ds.receive(パケット);
			文字列情報 = 新しい文字列(packet.getData(), 0, packet.getLength());
			System.out.println("情報を受信: " + info);
		} キャッチ (例外 e) {
			e.printStackTrace();
		}
	}

	/**
	 * 応答パケットを要求元に送信する */
	パブリック静的void応答(SocketAddressアドレス、文字列情報){
		試す {
			DatagramPacket dp = 新しい DatagramPacket(info.getBytes(), info.getBytes().length, address);
			dp.setData(info.getBytes());
			ds.send(dp);
		} キャッチ (例外 e) {
			e.printStackTrace();
		}		
	}
}

実行後、クライアントは正常にデータを送受信できるようになります。

実際に使用する場合は、システム スタートアップ項目を設定して、init 接続オブジェクトとアドレスを初期化し、使用時に例外をキャプチャします。

接続オブジェクトが毎回作成され、頻繁に使用される場合、通常、システムは数分以内にクラッシュします。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • UDP シンプル サーバー クライアント コード例
  • Python UDPプログラミングの詳細な説明
  • TCP/UDP プロトコルを使用した C# サンプル コード
  • UDP チャット プログラムに基づく Java ネットワークの例の分析
  • Java シミュレーション UDP 通信サンプル コード
  • PythonはUDPプログラム通信プロセス図を実装します
  • PythonはUDPプロトコルによるファイル転送を実装する
  • Java UDP 通信クライアントとサーバーの例の分析

<<:  JavaScript 配列重複排除ソリューション

>>:  2 つの MySQL ユーザー削除ステートメント (delete user と drop user) の違い

推薦する

Windows での MySQL の詳細なインストール手順と基本的な使用方法

目次1. MySQLをダウンロードする2. MySQLをインストールする3. MySQL の基本的な...

MySQL 面接の質問: ハッシュ インデックスの設定方法

B-Tree インデックスに加えて、MySQL は次のインデックスも提供します。ハッシュインデックス...

VSCode+CMake+Clang+GCC 環境構築チュートリアル (Win10 の場合)

大学院入試に備えて、C/C++ を使って基本的なデータ構造とアルゴリズムを実装する予定です。アルゴリ...

Windows 10 での mysql-8.0.17-winx64 のインストール方法

1.公式サイトからダウンロードして解凍する参考: ダウンロード後、zip 圧縮ファイル (mysql...

Pycharmとsshリモートアクセスサーバーdockerの詳細なチュートリアル

背景: 一部の実験はサーバー上で完了する必要があります。したがって、リモート サーバー上のコードをロ...

HTML の左右レイアウトのサンプルコード

CS: ...コードをコピーコードは次のとおりです。 html,body{ margin:0px; ...

MySQLがbinlogファイルを手動で登録し、マスタースレーブ異常を引き起こす理由

1. 問題の原因友人の @水米田 から、POSITION に基づくマスタースレーブについて質問があり...

Websocket+Vuexはリアルタイムチャットソフトウェアを実装します

目次序文1. 効果は図の通りです2. 具体的な実施手順1. Vuexの紹介2.webscoked実装...

Apache SkyWalkingのセルフモニタリングを素早く有効にする方法を説明します

1. Prometheusテレメトリデータを有効にするデフォルトでは、テレメトリは次のように無効にな...

MySQL 5.7.18 無料インストールバージョンの設定チュートリアル

MySQL 5.7.18 無料インストール版のインストールチュートリアルMySQL は現在、世界で最...

Linux ブートシステム方式の分析

この記事では、Linux システムを起動する方法について説明します。ご参考までに、詳細は以下の通りで...

初心者向けウェブサイト構築チュートリアルの概要

これら 6 つの記事を書いた後、私は少し混乱し始めました。次にどこに書けばいいのか分かりません。ドメ...

MySQL 5.7.18 のインストールと設定方法のグラフィックチュートリアル (CentOS7)

LinuxにMySQL 5.7.18をインストールする方法1. MySQLをダウンロードします。公...

div が隠しテキストを超え、div 部分の向こうの CSS コードを隠します

隠れる前に:隠れた後: CS: ...コードをコピーコードは次のとおりです。オーバーフロー:非表示;...