ソフトウエア基礎
ohmi@rsch.tuis.ac.jp

ネットワーク(3) 解答例

課題net-22

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

public class DaytimeServer {
    static int port = 10013;
    
    public static void main(String[] args) {
	try {
	    ServerSocket server = new ServerSocket(port);
	    Socket sock = null;
	    System.out.println("Server Ready");
	    while(true) {
		try {
		    sock = server.accept(); // クライアントからの接続を待つ

		    System.out.println("Connected");
		    BufferedReader in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
		    PrintWriter out = new PrintWriter(sock.getOutputStream());
		    Date d = new Date();
		    out.print(d + "\r\n");
		    out.flush();
		    sock.close(); // クライアントからの接続を切断
		    System.out.println("Connection Closed");
		} catch (IOException e) {
		    System.err.println(e);
		}
	    }
	} catch (IOException e) {
	    System.err.println(e);
	}
    }
}

課題net-23

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

public class ReversingEchoServer {
    static int port = 10007;
    
    public static void main(String[] args) {
	try {
	    ServerSocket server = new ServerSocket(port);
	    Socket sock = null;
	    System.out.println("Server Ready");
	    while(true) {
		try {
		    sock = server.accept(); // クライアントからの接続を待つ

		    System.out.println("Connected");
		    BufferedReader in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
		    PrintWriter out = new PrintWriter(sock.getOutputStream());
		    String s, t;
		    while((s = in.readLine()) != null) { // 一行受信
			t = "";
			for (int i = s.length()-1; i >= 0; i--) {
			    t += s.charAt(i); // 逆順にして1文字づつtに追加
			}
			out.print(t + "\r\n"); // 一行送信
			out.flush();
			System.out.println(t);
		    }
		    sock.close(); // クライアントからの接続を切断
		    System.out.println("Connection Closed");
		} catch (IOException e) {
		    System.err.println(e);
		}
	    }
	} catch (IOException e) {
	    System.err.println(e);
	}
    }
}

課題net-24

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

public class AlphabetReversingEchoServer {
    static int port = 10007;
    
    public static void main(String[] args) {
	try {
	    ServerSocket server = new ServerSocket(port);
	    Socket sock = null;
	    System.out.println("Server Ready");
	    while(true) {
		try {
		    sock = server.accept(); // クライアントからの接続を待つ

		    System.out.println("Connected");
		    BufferedReader in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
		    PrintWriter out = new PrintWriter(sock.getOutputStream());
		    String s, t;
		    while((s = in.readLine()) != null) { // 一行受信
			t = "";
			for (int i = 0; i < s.length(); i++) {
			    char c = s.charAt(i);
			    if (c >= 'A' && c <= 'Z') { // 大文字の場合
				t += (char)(c + 'a' - 'A'); // 小文字に変換
			    } else if (c >= 'a' && c <= 'z') { // 小文字の場合 
				t += (char)(c + 'A' - 'a'); // 大文字に変換
			    } else { // その他
				t += c; // 変換しない
			    }
			}
			out.print(t + "\r\n"); // 一行送信
			out.flush();
			System.out.println(t);
		    }
		    sock.close(); // クライアントからの接続を切断
		    System.out.println("Connection Closed");
		} catch (IOException e) {
		    System.err.println(e);
		}
	    }
	} catch (IOException e) {
	    System.err.println(e);
	}
    }
}

※ アルファベットを変換する際にchar型へのキャストを行なっている。 これを行わないとint型と解釈され、文字コード値が結果として出力されてしま う。

課題net-25

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

public class DateWebServer {
    static int port = 10080;
    
    public static void main(String[] args) {
	try {
	    ServerSocket server = new ServerSocket(port);
	    Socket sock = null;
	    String[] html_body = {
		"<html><head>",
		"<title>Show Date</title>",
		"</head>",
		"<body>",
		"<h1>", 
		"",
		"</h1>",
		"</body>",
		"</html>"};
	    int content_length = 0;
	    int i;
	    for (i = 0; i < html_body.length; i++) {
		content_length += html_body[i].length() + 2;
	    }

	    System.out.println("*** Server Ready ***");
	    while(true) {
		try {
		    sock = server.accept();
		    System.out.println("*** Connected ***");
		    boolean connected = true;
		    BufferedReader in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
		    PrintWriter out = new PrintWriter(sock.getOutputStream());
		    String s;
		    while(true) {
			s = in.readLine();
			if (s == null) {
			    out.print("HTTP/1.1 400 Bad Request\r\n");
			    out.flush();
			    connected = false;
			    break;
			}
			if (s.equals("")) break; 
			System.out.println(s);
		    }
		    if (connected) {
			Date d = new Date();
			html_body[5] = d.toString();
			out.print("HTTP/1.0 200 OK\r\n");
			out.print("Server: Simple Java Web Server \r\n");
			out.print("Content-length: " + 
				  (content_length + html_body[5].length()) +
				  "\r\n");
			out.print("Content-Type: text/html\r\n");
			out.print("\r\n");
			for (i = 0; i < html_body.length; i++) {
			    out.print(html_body[i] + "\r\n");
			}
			out.flush();
		    }
		    sock.close();
		    System.out.println("*** Connection Closed ***");
		} catch (IOException e) {
		    System.err.println(e);
		}
	    }
	} catch (IOException e) {
	    System.err.println(e);
	}
    }
}

※ html_body[5]を最初は空にして、バイト数を数え、 HTTPレスポンスを返す時に、html_body[5]に日時の文字列を代入している。 Content-lengthヘッダを出力する際に事前に数えたバイト数と、 現在のhtml_body[5]のバイト数を足すことで全体のバイト数を求めている。

html_body[5] = d.toString() として、 Dateオブジェクトを文字列に変換している。 勧められないが、 html_body[5] = "" + d としても 正常に動作する。空の文字列"" に dを追加する場合に、自動的にtoString() が呼ばれて、文字列に変換されるからである。

課題net-26

	    String host = "www.rsch.tuis.ac.jp";
	    String path = "/~ohmi/software-basic/network-test.html";

以上のhostとpathに代入している内容を修正することになる。実行結果は省略する。

課題net-27

	    String from = "s03888xx@edu.tuis.ac.jp";
	    String to = "s03999yy@edu.tuis.ac.jp";

以上のfromとtoに代入している内容を修正することになる。 実行結果は省略する。

課題net-28

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

public class LoggedWebServer {
    static int port = 10080;
    
    public static void main(String[] args) {
	try {
	    ServerSocket server = new ServerSocket(port);
	    Socket sock = null;
	    String[] html_body = {
		"<html><head>",
		"<title>Network test</title>",
		"</head>",
		"<body>",
		"<h1>Network test page</h1>",
		"<address>joho-taro@hogehoge.tuis.ac.jp</address>",
		"</body>",
		"</html>"}; // 送信するHTMLの内容
	    final String log_filename = "access_log";
	    int content_length = 0;
	    int i;
	    // HTMLの内容のバイト数を数える
	    for (i = 0; i < html_body.length; i++) {
		content_length += html_body[i].length() + 2;
	    }
	    PrintWriter log = new PrintWriter(new FileWriter(log_filename));

	    System.out.println("*** Server Ready ***");
	    while(true) {
		try {
		    sock = server.accept(); // 接続を待つ
		    System.out.println("*** Connected ***");
		    boolean connected = true; // まだ接続中かどうか?
		    BufferedReader in = new BufferedReader(
                        new InputStreamReader(sock.getInputStream()));
		    PrintWriter out = new PrintWriter(sock.getOutputStream());
		    String s;
		    // HTTPリクエストを受信する
		    s = in.readLine();
		    if (s == null || !s.startsWith("GET")) {
			// ソケットが切断された もしくは GETメソッドでない
			out.print("HTTP/1.1 400 Bad Request\r\n");
			out.flush();
			connected = false;
		    } else {
			StringTokenizer st = new StringTokenizer(s, " ");
			st.nextToken();
			String path = st.nextToken();
			String ver = st.nextToken();
			log.println(sock.getInetAddress() + " " +
				    path + " " + ver);
			log.flush();
		    }
 		    while(connected) {
			s = in.readLine();
			if (s.equals("")) break; // 空行に到達した
			System.out.println(s);
		    }
		    // HTTPレスポンスを返す
		    if (connected) { 
		        // HTTPステータス行の送信
			out.print("HTTP/1.1 200 OK\r\n");
		        // HTTPヘッダ部の送信
			out.print("Server: Simple Java Web Server \r\n");
			out.print("Content-Length: " + content_length + "\r\n");
			out.print("Connection: close\r\n");
			out.print("Content-Type: text/html\r\n");
			// 空行(ヘッダ部終了)の送信
			out.print("\r\n");
			// 本文(この場合HTML)の送信
			for (i = 0; i < html_body.length; i++) {
			    out.print(html_body[i] + "\r\n");
			}
			out.flush();
		    }
		    sock.close(); // ソケットを切断する
		    System.out.println("*** Connection Closed ***");
		} catch (IOException e) {
		    System.err.println(e);
		}
	    }
	} catch (IOException e) {
	    System.err.println(e);
	}
    }
}

ソフトウエア基礎

ohmi@rsch.tuis.ac.jp

Valid HTML 4.01!