package info.istlab.ServerTester; import java.io.IOException; import java.net.BindException; import java.net.InetSocketAddress; import java.net.ServerSocket; import javax.swing.JOptionPane; public class Server implements Runnable { public ServerSocket serverSocket; Thread thread; int expectedPort; String expectedAddress; boolean bindFailed = false; public static void invokeMain(String[] args, String className) { try { if (args.length == 0) { Class.forName("info.istlab.ServerTester." + className).getConstructor().newInstance(); } else if (args.length == 1) { if (isNumeric(args[0])) { // 数値の場合はポート番号として扱う Class.forName("info.istlab.ServerTester." + className).getConstructor(int.class) .newInstance(Integer.parseInt(args[0])); } else { // 数値でない場合はバインドアドレスとして扱う Class.forName("info.istlab.ServerTester." + className).getConstructor(String.class) .newInstance(args[0]); } } else if (args.length == 2) { Class.forName("info.istlab.ServerTester." + className) .getConstructor(int.class, String.class).newInstance(Integer.parseInt(args[0]), args[1]); } else { System.err.println("Usage: java info.istlab.ServerTester." + className + " [port] [bind-address]"); } } catch (Exception e1) { e1.printStackTrace(); } } public static boolean isNumeric(String str) { if (str == null || str.isEmpty()) { return false; } try { Integer.parseInt(str); return true; } catch (NumberFormatException e) { return false; } } public Server(int port, String bindaddress) { expectedPort = port; expectedAddress = bindaddress; try { serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(bindaddress, port)); bindFailed = false; } catch (BindException bex) { bindFailed = true; JOptionPane.showMessageDialog(Host.mainhost, getClass().getName() + " 起動時に、サーバソケットのバインドに失敗しました。\n\nポート " + expectedPort + " とバインドアドレス " + expectedAddress + " の組み合わせは使用されています。\n既存のサービスを停止するか、ポート番号/バインドアドレスを変更してください。", "エラー", JOptionPane.ERROR_MESSAGE); } catch (IOException e) { System.err.println(e); // System.err.println("バインド失敗。ポート番号 " + port + " (Bind-address: " + bindaddress // + " 向け) がすでにつかわれているようです"); // System.err.println("ポート番号またはバインドアドレスを変更してください。"); // System.err.println("またはコマンド killall java を実行して全てのJavaプロセスを終了してください。"); } System.out.println(getClass().getName() + " [" + bindaddress + ":" + port + "] started."); } public void handleRequest() { } public void start() { thread = new Thread(this); thread.start(); } public void run() { while (thread != null) { if (serverSocket.isClosed()) { thread = null; } if (thread != null && !serverSocket.isClosed()) { try { handleRequest(); } catch (Exception e) { System.err.println(e); thread = null; } } } } public String getBindAddress() { if (serverSocket == null) { return "/null"; } if (serverSocket.getInetAddress() == null) { return "/null"; } return serverSocket.getInetAddress().toString(); } public int getPort() { return serverSocket.getLocalPort(); } public boolean isClosed() { return serverSocket.isClosed(); } public String getExpectedAddress() { return expectedAddress; } public int getExpectedPort() { return expectedPort; } public void restart() { try { serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(expectedAddress, expectedPort)); bindFailed = false; start(); } catch (BindException bex) { bindFailed = true; JOptionPane.showMessageDialog(Host.mainhost, getClass().getName() + " 起動時に、サーバソケットのバインド失敗しました。\n\nポート " + expectedPort + " とバインドアドレス " + expectedAddress + " の組み合わせは使用されています。\n既存のサービスを停止するか、ポート番号/バインドアドレスを変更してください。", "エラー", JOptionPane.ERROR_MESSAGE); } catch (IOException e) { e.printStackTrace(); } } public void close() { try { serverSocket.close(); } catch (IOException e) { System.err.println(e); } thread = null; } }