Shammer's Philosophy

My private adversaria

Java Socket API Sample1(EchoClient)

昨日に続き、Socket API のサンプルの続き。自分が送ったメッセージをそのままサーバーから受け取り、
それを表示するクライアントのサンプル。ほとんど、http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-06520-0
同じであることは昨日のサーバー側と一緒。

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPEchoClient {
  public static void main(String[]args) {
    if( !(args.length == 2 || args.length == 3) ) {
      System.err.println("Usage: java TCPEchoClient <Server> <Word> <Port>");
      System.err.println("Port is optional.");
      System.exit(1);
    }
    String server = args[0];
    String sendMessage = args[1];
    byte[] message = sendMessage.getBytes();
    byte[] receivedByteMessage = new byte[message.length];
    int serverPort = (args.length == 3) ? Integer.parseInt(args[2]) : 7;
    Socket socket = null;
    try {
      socket = new Socket(server, serverPort);
      System.out.println("Connected to server ... sending echo string.");
      InputStream in = socket.getInputStream();
      OutputStream out = socket.getOutputStream();
      out.write(message);
      int totalReceivedByte = 0;
      int receivedByte = 0;
      while( totalReceivedByte < message.length ) {
        receivedByte = in.read(receivedByteMessage, totalReceivedByte, message.length - totalReceivedByte);
        if( receivedByte == -1 ){
          throw new java.net.SocketException("Connection closed prematurely");
        }
        totalReceivedByte = totalReceivedByte + receivedByte;
        System.out.println(new String(receivedByteMessage));
      }
      String receivedMessage = new String(receivedByteMessage);
      System.out.println("Received:" + new String(receivedByteMessage));
      System.out.println("Received message length:" + receivedMessage.length());
    }
    catch( Exception e ) {
      e.printStackTrace();
    }
    finally {
      try {
        if( socket != null ) {
          socket.close();
        }
      }
      catch( Exception e ) {
        e.printStackTrace();
      }
    }
  }
}

クライアント側では、送受信するメッセージサイズが実行時にはあらかじめわかっている。
そのため、サンプルの実装は非常にシンプルにできる。しかし、HTTPサーバーとクライアントの
やり取りをイメージするとなると、クライアントはリクエストのサイズを何らかの方法で知る必要がある。
HTTPの場合は、それがContent-Lengthの長さであったり、サーバーからのFINだったりするのだろうが、
今回の実装ではそういうことは考えられていない。単純に、自身が送ったのと同じ長さのバイト配列を
受け取ったらクローズするような実装になっている。この点をこれから拡張していきたい。