Java ネットワーク プログラミングに関する経験

零下一度
リリース: 2017-07-17 13:11:59
オリジナル
2511 人が閲覧しました

最近、Java ネットワーク プログラミングを勉強しています。聞いたことはありますが、真剣に理解したことがありません。ここ数日、私は突然興味を持ち、とても不思議な気がして、具体的にどのような状況なのか知りたくなりました。ソケットは通常「ソケット」と呼ばれ、IP アドレスとポートを表すために使用されます。通信チェーンのハンドルです。インターネット上のホストは通常​​、複数のサービス ソフトウェアを実行し、複数のサービスを同時に提供します。各サービスはソケットを開き、異なるポートに異なるサービスに対応します。

ソケットは電話のソケットに非常に似ています。全国電話ネットワークを例にとると、通話中の 2 つの当事者は相互に通信する 2 つのプロセスに相当し、市外局番はそのネットワーク アドレスであり、その地域内のユニット内の交換機はホストに相当します。ホストは各ユーザーにソケット番号に相当する社内番号を割り当てます。ユーザーは電話をかける前に、まず電話機を所有している必要があります。これはソケットを申請することに相当し、同時に相手の番号を知っている必要があります。これは相手が固定ソケットを持っていることに相当します。次に、相手に電話をかけます。これは、接続要求を発行することと同じです (相手が同じ地域にいない場合は、相手の市外局番もダイヤルする必要があります。これは、ネットワーク アドレスを与えることと同じです)。相手が存在し、アイドル状態である場合 (他の通信ホストがオンになっていて接続要求を受け入れることができる場合に相当)、受話器を取ると、両者は正式に通話できるようになり、接続が成功したことになります。 2 者間の通話のプロセスは、一方が電話機に信号を送信し、もう一方が電話機から信号を受信するプロセスです。これは、ソケットにデータを送信し、ソケットからデータを受信することに相当します。通話終了後、一方が電話を切ることは、ソケットを閉じて接続をキャンセルすることと同じです。


電話システムでは、一般的なユーザーは、通話を確立するプロセス、音声送信のプロセス、および電話システム全体の技術的な詳細のみを認識できます。彼にとっては透明であり、これはソケットのメカニズムと非常によく似ています。 Socket はプロセス通信を実現するためにインターネットの通信機能を利用しますが、通信機能の詳細は問わないため、十分な通信能力が得られれば問題ありません。

これらはBaidu百科事典の定義と説明ですが、非常に理解しにくい以前の説明とは異なり、非常に理解しやすくなっています。専門用語が多すぎて理解するのが非常に困難でした。

ソケット通信の実装手順:

1. ServerSocket と Socket を作成します
2. Socket に接続されている入出力ストリームを開きます 3. プロトコル (通常は TCP/UDP) に従って Socket 上で読み取りおよび書き込み操作を実行します 4.入力/出力ストリームを閉じ、Socket を閉じます

Socket プログラミング

1 つは ServerSocket で、もう 1 つは Socket です。 Socket を介してサーバーとクライアントの間に接続が確立され、通信できるようになります。まず、ServerSocket はサーバー側の特定のポートをリッスンし、クライアントが Socket を持っていることを検出し、それに接続しようとすると、その Socket の接続要求を受け入れ、サーバー側で対応する Socket を確立して通信します。それと。このように、クライアント用とサーバー用の 2 つのソケットが存在します。

ソケット間の通信は実際には非常に単純です。サーバーはソケットの出力ストリームに何かを書き込み、クライアントはソケットの入力ストリームを通じて対応するコンテンツを読み取ることができます。ソケットとソケットの間には双方向接続があるため、クライアントは対応するソケット出力ストリームに内容を書き込むこともでき、サーバー上の対応するソケット入力ストリームは対応するコンテンツを読み取ることができます。


以下はクライアントの読み書きとサーバーの読み書きの例です
Java ネットワーク プログラミングに関する経験サーバー側のコード

public class Server {
public static void main(String args[]) throws IOException {
      //定义一个ServerSocket监听在端口8888上  
      int port = 8888; 
      int i=1; //连接计数
      //server尝试接收其他Socket的连接请求,
      ServerSocket server = new ServerSocket(port);  
      //server的accept方法是阻塞式的 ,即等待着客户端的请求
      Socket socket = server.accept();  
      System.out.println("连接"+i++);
      //跟客户端建立好连接,我们就可以获取socket的InputStream,从中读取客户端发过来的信息。  
      Reader reader = new InputStreamReader(socket.getInputStream());    
      char chars[] = new char[64];  
      int len;  
      StringBuilder sb = new StringBuilder();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) { //遇到eof时就结束接收  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(temp);  
      }  
      System.out.println("from client: " + sb);  
      //读完后写数据 
      Writer writer = new OutputStreamWriter(socket.getOutputStream());  
      writer.write("Hello Client:我是服务端输入数据"); 
      //释放资源
      writer.flush();  
      writer.close(); 
      reader.close();  
      socket.close();  
      server.close(); 
   }  
}
ログイン後にコピー

出力

注意点

Java ネットワーク プログラミングに関する経験

InputStreamからデータを読み込むサーバーの動作入力ストリームからデータが読み取られない場合、プログラムはクライアントがソケット出力ストリームにデータを書き込むか、ソケット出力ストリームを閉じるまでそこに留まります。もちろん、クライアントの Socket にも同じことが当てはまります。

  • クライアントによって送信されたデータを入力ストリームから読み取り、そのデータをクライアントへの出力ストリームに書き込み、対応するリソース ファイルを閉じます。実際、上記のコードは期待どおりに実行されない可能性があります。これは、上記の while ループでは、データが読み取られるときにループ本体が実行され、それ以外の場合はブロックされるためです。この状況では、通常、クライアントから送信されたデータに終了マークが含まれている場合、それは現在のデータが送信されたことを意味します。ループ。

  • 在上述代码中,当服务端读取到客户端发送的结束标记,即“eof”时就会结束数据的接收,终止循环,这样后续的代码又可以继续进行了。

客户端代码

public class Client {
 public static void main(String args[]) throws Exception {  
      //为了简单起见,所有的异常都直接往外抛  
      String host = "192.168.74.1";  //要连接的服务端IP地址  
      int port = 8888;   //要连接的服务端对应的监听端口  
      //与服务端建立连接  
      Socket client = new Socket(host, port);  
      //建立连接后就可以往服务端写数据了  
      Writer writer = new OutputStreamWriter(client.getOutputStream());  
      writer.write("Hello ,我是客户端输入数据");
      writer.write("eof"); 
      writer.flush();//写完后要记得flush  
      //读取来自服务端数据
      Reader reader = new InputStreamReader(client.getInputStream());  
      char chars[] = new char[64];  
      int len;  
      StringBuffer sb = new StringBuffer();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) {  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(new String(chars, 0, len));  
      }  
      System.out.println("from server: " + sb);
      writer.close(); 
      reader.close();  
      client.close();  
   }  
}
ログイン後にコピー

输出

Java ネットワーク プログラミングに関する経験

注意点

  • 过程:先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环,解决方法和服务端一样,用一个结束标志。

  • 对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。

以上がJava ネットワーク プログラミングに関する経験の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート