Java
Eclipse
HTTP
TCP
Wireshark

第二章JAVAによるネットワークプログラミング phttpd 三箇所でException収集

phttpd「基礎からわかるTCP/IP JAVAネットワークプログラミング」小高知宏 著 オーム社

基礎.png

「第二章JAVAによるネットワークプログラミング」のphttpd.java三箇所でException収集

phttpd : pseudo hyper text transfer protocol daemon(擬似HTTP処理)

導入、コンパイル、デバッグ方法は下記参照

「基礎からわかるTCP/IP JAVAネットワークプログラミング」Eclipseでコンパイル。Wiresharkでデバッグ。
https://qiita.com/drafts/14519536b827fdadb32e/

以下の項目に手を加えた。手を加えた行は///を行末等に記載。

  • どの場所で、どういうExceptionが発生したかをコンソールへ出力。
  • out.writeの出力をコンソールへも出力。
  • java.util.*は使っていないという警告が出た。削除。
  • forループは{}で囲った。
  • 直接の数字(magic number)を意味のわかる変数にした。backlog, hppdp(port), buff_size
  • 注釈で、英語に翻訳すると関数名に近い日本語は削った。
  • 日本語出力ではなく英語出力に。(文字コードの問題に振り回されたくない、海外でも紹介したい。)
phttpd.java
import java.io.*;
import java.net.*;
/// remove java.util.*

public class phppd {
 public static void main(String args[]) {
    ServerSocket servsock = null; 
    Socket sock;  
    OutputStream out;
    BufferedReader in;
    FileInputStream infile=null;
    int buff_size = 1024;///
    byte buff[] =new byte[buff_size];
    boolean cont =true;
    int i; // loop counter
    int backlog=300; int htpp=8080;///
    try{
      servsock = new ServerSocket(htpp, backlog);///
      while(true){
        sock = servsock.accept();  
        System.out.println("Connection Request"+(sock.getInetAddress()).getHostName());
        try {
         infile=new FileInputStream(args[0]);
        } catch(Exception e){
         System.out.println("1");///
         System.out.println(e);///
         System.exit(1);
        }
        in=new BufferedReader(new InputStreamReader(sock.getInputStream()));;
        out=sock.getOutputStream();
        for(i=0;i<2;++i) {///
          in.readLine();
        }///
        cont=true;
        while(cont) {
         try {
          int n=infile.read(buff);
          System.out.println("4");///
          System.out.println(buff);///
          out.write(buff,0,n);
         } catch(Exception e){
          System.out.println("2:");///
          System.out.println(e);///
          cont=false;
         }
        }
        sock.close();
        infile.close();
      }
    } catch(IOException e){
     System.out.println("3");///
     System.out.println(e);///
     System.exit(1);
    }
  }
}

 三箇所ともで、Exceptionが収集できた。

error 1

Connection Request localhost
1
java.io.FileNotFoundException: index.html (No such file or directory)

index.htmlファイルを作っていなかった。

error 2

2
Connection Request localhost
2
java.net.SocketException: Broken pipe (Write failed)

error 2-1

Connection Request localhost
2
java.lang.ArrayIndexOutOfBoundsException: len == -1 off == 0 buffer length == 1024

実行前にWiresharkを起動した。
http.png

Wiresharkを見ると、< /html >まで送受信している。
ブラウザ(Safari バージョン11.0.1 (12604.3.5.1.1))の表示は
page.png

おお、http/0.9だからダメなんだ。http/1.1とかで送る方法を捜索中。

error 3

3
java.net.BindException: Address already in use (Bind failed)

前に起動したphttpdを終わらずに次を起動したらしい。

$ ps -ax | grep phppd
10427 ??         0:08.61 /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -classpath /Users/administrator/eclipse-workspace/phppd/bin phppd index.html
10714 ??         0:07.68 /Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:51095 -Dfile.encoding=UTF-8 -classpath /Users/administrator/eclipse-workspace/phppd/bin phppd index.html
13190 ttys000    0:00.00 grep phppd

$ su Administrator
Password:
$ kill -9 10427
$ kill -9 10714

2つも動いているのはなぜ?他の時は、次は起動できなかったので1つしかない。

<この項は書きかけです。逐次追記します。>
「基礎からわかるTCP/IP JAVAネットワークプログラミング」Eclipseでコンパイル。Wiresharkでデバッグ。
https://qiita.com/drafts/14519536b827fdadb32e/
には、「JAVAを一度も触ったことがない方にお勧め。20年経った今でも有効」
って書いたからには、動くように直さなくては、、、。

情報処理技術者試験 ネットワークスペシャリストに合格 
https://qiita.com/kaizen_nagoya/items/407857392ca5c5677ee4

通信エミュレータの移植
https://qiita.com/drafts/ce505bbea4229b83e93b

Macintosh対応「基礎からわかるTCP/IP アナライザ作成とパケット解析 Linux/FreeBSD対応」小高知宏 オーム社
https://qiita.com/kaizen_nagoya/items/517411b42fc5ceabd581