(O+P)ut

(O+P)ut

(O+P)ut = Out + Put >> OutPut

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

f:id:mtiit:20181005085944j:plain

はじめに

最近、通信系のプログラムの勉強をしていた際に Java で通信するコードを動かしたのでそのメモとプログラムを紹介します。
必要なのはJavaが動くPC1台のみです。

Javaでのネットワーク通信

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

ちなみにですが、OpenVPNでも同じようにサーバクライアントという用語が出てきます。
そちらについても入門記事を記載しているので興味があれば合わせて参照ください。
mti.hatenablog.com


2つの通信プログラム

さて、今回は同じパソコンの中にサーバー側とクライアント側でプログラムを二つ用意します。

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

クライアント側の設計概要

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

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();

上のように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);
  }
 }
}

動作結果

実際にサーバー側のプログラムを実行します。おそらく何も表示されず待機されるはず。その後にもう一つターミナルを開いて、クライアント側のプログラムを実行します。
上のサンプルコードで言えば、Netclockを実行後、Readnetを実行します。
コードを見ればわかりますが、Netclockは引数なしで実行、Readnetは二つの引数で実行します。一つ目の引数はサーバのIPアドレス、二つ目はポート番号です。


今回はサーバとクライアントを同じパソコンで実行しますので、Readnetの第一引数は localhost、第二引数はNetclock側のソケットを6000にしているので6000とします。

実行結果はこんな感じになるかと思います。

java Readnet localhost 6000

Sun Apr 19 17:47:26 JST 2015

すごいシンプルなプログラムなので、コードも読みやすいと思います。

ちなみに、もっと詳しく知りたい方は以下の2冊を手にとってみることをお勧めします。良書でした。

以上です。