(O+P)ut

頭の整理のために、Slerで働く若手インフラエンジニアが、【 (O+P)ut = OutPut 】していく場です。

【Java】パソコン一台で通信プログラムを動かしてみる

最近、通信系のプログラムを理解しないといけない必要に迫られてるんで色々と本を読んで勉強しているのですが、一通りまとまってきたので一番とっつきやすかったプログラムを紹介します。
同じような境遇の方の助けになれば!

ネットワークの通信では「クライアントサーバモデル」がよく出てきます。例えばネットサーフィンなんかも、クライアントである私たちがサーバー側にリクエストを送っているっていう構図です。

今回はサーバー側とクライアント側でプログラムを二つ作ります。
通信を行う上で肝心なことは、クライアント側はサーバー側のポートをしっかり指定して接続しようとし、サーバー側はクライアント側から接続されてもいいようにポートを開放しておく、ということですかね。

クライアント側ではデータを読み取るために

Socket hoge = null;

を準備して,

hoge = new Socket("IPアドレス",(整数)ポート番号);

という風にソケットを作成します。あとはファイルからの読み込みと同じように,InputStreamでデータを受け取って...といった感じです(下にサンプルコードあり)。
第一引数でIPアドレスを,第二引数でポート番号を指定するクライアント側のプログラムのコードは以下にあるのでコピペしてコンパイルすればそのまま動くと思います.

import java.io.*;
import java.net.*;

public class Readnet {

 public static void main(String[] args) {
  byte[] buff = new byte[1024];
  Socket readsocket = null;
  InputStream instr = null;
  boolean cont = true;
  
  try {
    readsocket = new Socket(args[0],Integer.parseInt(args[1]));
    instr = readsocket.getInputStream();
  }
  catch(Exception e) {
   System.err.println("Network Error");
   System.exit(1);
  }
		
  while(cont) {
   try {
    int n = instr.read(buff);
    System.out.write(buff,0,n);
    }
   catch(Exception e) {
    cont = false;
   }
  }
   
  try {
   instr.close();
  }
  catch(Exception e) {
   System.err.println("Network Error");
   System.exit(1);
  }
 }
}

次はサーバー側です。こちらも似たように

ServerSocket hoge2;

を作って

hoge2 = new ServerSocket(ポート番号,最大接続数)

とソケットを作成します。
クライアント側の違いとしては、作成したサーバーソケットに対する接続を待ち受けるオブジェクトを作り、acceptメソッドを使用することで接続を常に受け付けるようにすることですね。

Socket sock = hoge2.accept();

こんな感じ。

サーバー側のプログラムの全体は以下です。これもそのままコピペで動くはず。単なる文字列を返してもいいんですけど,せっかくなのでDateを使って日時を返します。

import java.io.*;
import java.net.*;
import java.util.Date;

public class Netclock {
 public static void main(String args[]) {
  ServerSocket servsock = null;
  Socket sock;
  OutputStream out;
  String outstr;
  Date d;
 
  try {
   servsock = new ServerSocket(6000,100);
   while(true) {
    sock = servsock.accept();
    d = new Date();
    outstr = "\n" + d.toString() +"\n";
    out = sock.getOutputStream();
    
    for(int i=0;i<outstr.length();++i) {
     out.write((int)outstr.charAt(i));
    }
    out.write('\n');
    sock.close();
   }
  }
  catch(IOException e) {
   System.exit(1);
  }
 }
}

では実際にサーバー側のプログラムを実行します。おそらく何も表示されず待機されるはず。その後にもう一つターミナルを開いて、クライアント側のプログラムを実行します。

今回は同じパソコンなので,第一引数は localhost、第二引数はサーバー側のソケットを6000にしているので6000とします。
実行結果はこんな感じになるかと思います。

java Readnet localhost 6000

Sun Apr 19 17:47:26 JST 2015

すごいシンプルなプログラムですが、ご参考ください。*1

*1:ちなみに、Javaによるネットワークプログラミング[鶴沢偉伸],TCP/IP Javaネットワークプログラミング[小高知宏] は読破した本の中でも良本でした