最近、Java ネットワーク プログラミングを勉強しています。聞いたことはありますが、真剣に理解したことがありません。ここ数日、私は突然興味を持ち、とても不思議な気がして、具体的にどのような状況なのか知りたくなりました。ソケットは通常「ソケット」と呼ばれ、IP アドレスとポートを表すために使用されます。通信チェーンのハンドルです。インターネット上のホストは通常、複数のサービス ソフトウェアを実行し、複数のサービスを同時に提供します。各サービスはソケットを開き、異なるポートに異なるサービスに対応します。
ソケットは電話のソケットに非常に似ています。全国電話ネットワークを例にとると、通話中の 2 つの当事者は相互に通信する 2 つのプロセスに相当し、市外局番はそのネットワーク アドレスであり、その地域内のユニット内の交換機はホストに相当します。ホストは各ユーザーにソケット番号に相当する社内番号を割り当てます。ユーザーは電話をかける前に、まず電話機を所有している必要があります。これはソケットを申請することに相当し、同時に相手の番号を知っている必要があります。これは相手が固定ソケットを持っていることに相当します。次に、相手に電話をかけます。これは、接続要求を発行することと同じです (相手が同じ地域にいない場合は、相手の市外局番もダイヤルする必要があります。これは、ネットワーク アドレスを与えることと同じです)。相手が存在し、アイドル状態である場合 (他の通信ホストがオンになっていて接続要求を受け入れることができる場合に相当)、受話器を取ると、両者は正式に通話できるようになり、接続が成功したことになります。 2 者間の通話のプロセスは、一方が電話機に信号を送信し、もう一方が電話機から信号を受信するプロセスです。これは、ソケットにデータを送信し、ソケットからデータを受信することに相当します。通話終了後、一方が電話を切ることは、ソケットを閉じて接続をキャンセルすることと同じです。これらはBaidu百科事典の定義と説明ですが、非常に理解しにくい以前の説明とは異なり、非常に理解しやすくなっています。専門用語が多すぎて理解するのが非常に困難でした。
1. ServerSocket と Socket を作成します
2. Socket に接続されている入出力ストリームを開きます 3. プロトコル (通常は TCP/UDP) に従って Socket 上で読み取りおよび書き込み操作を実行します 4.入力/出力ストリームを閉じ、Socket を閉じます
Socket プログラミング
1 つは ServerSocket で、もう 1 つは Socket です。 Socket を介してサーバーとクライアントの間に接続が確立され、通信できるようになります。まず、ServerSocket はサーバー側の特定のポートをリッスンし、クライアントが Socket を持っていることを検出し、それに接続しようとすると、その Socket の接続要求を受け入れ、サーバー側で対応する Socket を確立して通信します。それと。このように、クライアント用とサーバー用の 2 つのソケットが存在します。
以下はクライアントの読み書きとサーバーの読み書きの例です
サーバー側のコード
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(); } }
出力
注意点クライアントによって送信されたデータを入力ストリームから読み取り、そのデータをクライアントへの出力ストリームに書き込み、対応するリソース ファイルを閉じます。実際、上記のコードは期待どおりに実行されない可能性があります。これは、上記の 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(); } }
过程:先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环,解决方法和服务端一样,用一个结束标志。
对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。
以上がJava ネットワーク プログラミングに関する経験の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。