読者です 読者をやめる 読者になる 読者になる

(O+P)ut

IT系の記事やその他諸々,不定期で更新していきます(∵)

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

テクノロジー 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ネットワークプログラミング[小高知宏] は読破した本の中でも良本でした