diff --git a/C#/webserver.cs b/C#/webserver.cs index 3369666..d11ba6c 100644 --- a/C#/webserver.cs +++ b/C#/webserver.cs @@ -10,10 +10,11 @@ class WebServer { + const int SERVER_PORT = 8888; static void Main(string[] args) { - // 8000番ポートで listen する - var ep = new IPEndPoint(IPAddress.Any, 8000); + // SERVER_PORTで listen する + var ep = new IPEndPoint(IPAddress.Any, SERVER_PORT); var listener = new TcpListener(ep); try { @@ -24,7 +25,7 @@ static void Main(string[] args) Console.WriteLine($"TcpListener.Start() failed: {e.ErrorCode}"); return; } - Console.WriteLine("open http://localhost:8000/ with your browser!"); + Console.WriteLine($"open http://localhost:{SERVER_PORT}/ with your browser!"); // クライアントからのコネクションを待ち受けるループ while (true) diff --git a/C/webserver.c b/C/webserver.c index 3760c98..9b0735c 100644 --- a/C/webserver.c +++ b/C/webserver.c @@ -3,11 +3,9 @@ * Author: Kota Abe */ -// Linux (CentOS7) とMacOS (10.14.6) で動作を確認済 -// C99規格で書いているので,コンパイルには "cc -std=c99 webserver.c" とする +// Linux (Ubuntu22) とMacOS (10.14.6) で動作を確認済 -#define _BSD_SOURCE // Linux requires for strdup() -#define _POSIX_C_SOURCE 200112L // for fdopen() +#define _DEFAULT_SOURCE #include #include @@ -20,6 +18,8 @@ void handle_get(FILE *fp, const char *path); void handle_client(int client_fd, struct sockaddr_in *client_addr); +#define SERVER_PORT 8888 + int main(int argc, char **argv) { // socket()はソケットを生成し,ファイル記述子(ソケットに割り当てられた整数値)を返す @@ -43,7 +43,7 @@ int main(int argc, char **argv) server_addr.sin_family = AF_INET; // IPv4アドレス // サーバ側のIPアドレスはANY(指定しない).htonlは4バイトをネットワークバイトオーダに変換 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); - server_addr.sin_port = htons(8000); // サーバ側のポート番号の指定.htonsは2バイトをネットワークバイトオーダに変換 + server_addr.sin_port = htons(SERVER_PORT); // サーバ側のポート番号の指定.htonsは2バイトをネットワークバイトオーダに変換 if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("bind"); exit(1); @@ -56,7 +56,7 @@ int main(int argc, char **argv) exit(1); } - printf("open http://localhost:8000/ with your browser!\n"); + printf("open http://localhost:%d/ with your browser!\n", SERVER_PORT); // クライアントからのコネクションを処理するためのループ while (1) { @@ -170,7 +170,7 @@ void handle_client(int client_fd, struct sockaddr_in *client_addr) */ void handle_get(FILE *fp, const char *path) { - if (strcmp(path, "/") == 0) { // http://localhost:8000/ へのアクセスの場合 + if (strcmp(path, "/") == 0) { // http://localhost:8888/ へのアクセスの場合 // C言語では連続した文字列は自動的に連結される fprintf(fp, "HTTP/1.0 200 OK\r\n" // ステータス行 @@ -182,7 +182,7 @@ void handle_get(FILE *fp, const char *path) "This server is implemented in C!\r\n" "\r\n" ); - } else { // 他のパス (http://localhost:8000/abc.html) などへのアクセスの場合,404エラー + } else { // 他のパス (http://localhost:8888/abc.html) などへのアクセスの場合,404エラー fprintf(fp, "HTTP/1.0 404 Not Found\r\n" // 404はNot Foundを表す "Content-Type: text/html\r\n" diff --git a/Elixir/webserver.exs b/Elixir/webserver.exs index c12f296..1f7da4d 100644 --- a/Elixir/webserver.exs +++ b/Elixir/webserver.exs @@ -7,9 +7,10 @@ defmodule WebServer do Author: Kota Abe """ def main(_args \\ []) do - {:ok, socket} = :gen_tcp.listen(8000, + server_port = 8888 + {:ok, socket} = :gen_tcp.listen(server_port, [:binary, packet: :line, active: false, reuseaddr: true]) - IO.puts("open http://localhost:8000/ with your browser!") + IO.puts("open http://localhost:#{server_port}/ with your browser!") loop_acceptor(socket) end diff --git a/Go/go.mod b/Go/go.mod new file mode 100644 index 0000000..6bd0de5 --- /dev/null +++ b/Go/go.mod @@ -0,0 +1 @@ +module main diff --git a/Go/webserver.go b/Go/webserver.go index a2bad1a..894963b 100644 --- a/Go/webserver.go +++ b/Go/webserver.go @@ -14,13 +14,15 @@ import ( "strings" ) +const SERVER_PORT = 8888 + func main() { - // 8000番ポートで listen する - listener, err := net.Listen("tcp", ":8000") + // SERVER_PORTでlistenする + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", SERVER_PORT)) if err != nil { panic("ListenTCP failed") } - fmt.Println("open http://localhost:8000/ with your browser!") + fmt.Printf("open http://localhost:%d/ with your browser!\n", SERVER_PORT) // クライアントからのコネクションを待ち受けるループ for { diff --git a/Java/src/ocu/WebServer.java b/Java/src/webserver/WebServer.java similarity index 94% rename from Java/src/ocu/WebServer.java rename to Java/src/webserver/WebServer.java index 0402229..1897c80 100644 --- a/Java/src/ocu/WebServer.java +++ b/Java/src/webserver/WebServer.java @@ -2,7 +2,7 @@ * A simple Web server implementation in Java * Author: Kota Abe */ -package ocu; +package webserver; import java.io.*; import java.net.InetSocketAddress; @@ -12,11 +12,12 @@ import java.util.List; public class WebServer { + static int SERVER_PORT = 8888; public WebServer() { // サーバソケットを作るには,ServerSocketのインスタンスを生成する // このtryはtry-with-resource文 (スコープを抜けると自動的にserver.close()が呼ばれる) try (ServerSocket server = new ServerSocket()) { - server.bind(new InetSocketAddress(8000)); // ポート番号の指定 + server.bind(new InetSocketAddress(SERVER_PORT)); // ポート番号の指定 while (true) { // コネクション確立を待ってブロックする.確立するとSocketインスタンスを返す try (Socket socket = server.accept()) { @@ -107,7 +108,7 @@ private void handleGet(BufferedReader reader, PrintWriter writer, String path) { } public static void main(String[] args) { - System.out.println("open http://localhost:8000/ with your browser!"); + System.out.printf("open http://localhost:%d/ with your browser!\n", SERVER_PORT); new WebServer(); } } diff --git a/JavaScript/webserver.js b/JavaScript/webserver.js index b94bfa9..8b335d6 100644 --- a/JavaScript/webserver.js +++ b/JavaScript/webserver.js @@ -11,6 +11,8 @@ // このプログラムでは低レベルの処理を見せるために"net"モジュールを使っている const net = require("net"); +const SERVER_PORT = 8888; + function main() { const server = net.createServer(); // サーバの作成 // JavaScriptでは基本的にイベントベースで処理を記述する @@ -21,8 +23,8 @@ function main() { server.on("connection", conn => { handleClient(conn); }); - server.listen(8000); // コネクションの待ち受けを開始する - console.log("open http://localhost:8000/ with your browser!"); + server.listen(SERVER_PORT); // コネクションの待ち受けを開始する + console.log(`open http://localhost:${SERVER_PORT}/ with your browser!`); // ここでmain関数は終わるが,裏でコネクションの確立を待っている } diff --git a/Python/webserver.py b/Python/webserver.py index 12152ed..73621e3 100644 --- a/Python/webserver.py +++ b/Python/webserver.py @@ -11,14 +11,16 @@ import socket import threading -import typing +import io + +SERVER_PORT=8888 def main(): server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - server_sock.bind(('', 8000)) + server_sock.bind(('', SERVER_PORT)) server_sock.listen(5) - print("open http://localhost:8000/ with your browser!") + print(f"open http://localhost:{SERVER_PORT}/ with your browser!") while True: client_sock, address = server_sock.accept() @@ -60,7 +62,7 @@ def handle_client(client_sock: socket.socket): print(f"unsupported method {method}") f.write("HTTP/1.0 501 Not Implemented\r\n") -def handle_get(f: typing.TextIO, path: str): +def handle_get(f: io.TextIOWrapper, path: str): """ GET要求を処理する """ if path == "/": s = """\ diff --git a/README.md b/README.md index 06cb7e6..aa75e26 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # tiny-web-servers -This repository contains implementations of tiny web servers written in C, C#, Elixir, Go, Java, JavaScript (on Node.js), Python, and Ruby. All implementations have the same functionality. +This repository contains implementations of tiny web servers written +in C, C#, Elixir, Go, Java, JavaScript (on Node.js), Python, and Ruby. +All implementations have the same functionality. -I wrote these to use as a material of network programming exercises in one of my lectures. +I wrote these to use as a material of network programming exercises in +one of my lectures. Note that comments in the source code are in Japanese. diff --git a/Ruby/webserver.rb b/Ruby/webserver.rb index 47dcf52..b4f7f63 100644 --- a/Ruby/webserver.rb +++ b/Ruby/webserver.rb @@ -11,9 +11,11 @@ require "socket" +SERVER_PORT = 8888 + def main() - puts("open http://localhost:8000/ with your browser!") - server = TCPServer.new('0.0.0.0', 8000) # サーバソケットの生成 + server = TCPServer.new('0.0.0.0', SERVER_PORT) # サーバソケットの生成 + puts("open http://localhost:#{SERVER_PORT}/ with your browser!") loop do client_socket = server.accept # コネクション確立を待つ # コネクションが確立したら,新しいスレッドを開始する @@ -43,8 +45,8 @@ def handle_client(sock) end if headers.length == 0 - puts("no header!") - return + puts("no header!") + return end req = headers[0].split(" ") # 先頭行を " " で分割する if req.length != 3 @@ -84,7 +86,7 @@ def handle_get(sock, path) - 404 Not Found + 404 Not Found #{path} is not found EOS