diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..93d50f7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,56 @@ +{ + // IntelliSense を使用して利用可能な属性を学べます。 + // 既存の属性の説明をホバーして表示します。 + // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "WhiteBoardServer", + "request": "launch", + "mainClass": "info.istlab.ServerTester.WhiteBoardServer", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "TimeServer", + "request": "launch", + "mainClass": "info.istlab.ServerTester.TimeServer", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "EchoServer", + "request": "launch", + "mainClass": "info.istlab.ServerTester.EchoServer", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "NetworkMaskExample", + "request": "launch", + "mainClass": "info.istlab.ServerTester.NetworkMaskExample", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "AddPanel", + "request": "launch", + "mainClass": "info.istlab.ServerTester.AddPanel", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "Current File", + "request": "launch", + "mainClass": "${file}" + }, + { + "type": "java", + "name": "App", + "request": "launch", + "mainClass": "info.istlab.ServerTester.App", + "projectName": "ServerTester" + } + ] +} \ No newline at end of file diff --git a/src/main/java/info/istlab/ServerTester/AddPanel.java b/src/main/java/info/istlab/ServerTester/AddPanel.java new file mode 100644 index 0000000..1e0d0c9 --- /dev/null +++ b/src/main/java/info/istlab/ServerTester/AddPanel.java @@ -0,0 +1,124 @@ +package info.istlab.ServerTester; + +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Enumeration; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.JTextField; +import javax.swing.SpinnerNumberModel; + +public class AddPanel extends JPanel { + Host host; + JComboBox servBox; + JTextField portField; + JComboBox bindBox; + JSpinner portSpinner; + + public AddPanel(Host _host) { + host = _host; + + String[] options = { "WebServer", "TimeServer", "ThreadTimeServer", "EchoServer", "ThreadEchoServer", + "WhiteBoardServer" }; + servBox = new JComboBox(options); + add(servBox); + + // Port用のJSpinnerを作成 + SpinnerNumberModel model = new SpinnerNumberModel(8081, 1024, 65535, 1); // 初期値、最小値、最大値、ステップ + portSpinner = new JSpinner(model); + add(portSpinner); + + ArrayList bindoptions = new ArrayList(); + bindoptions.add("127.0.0.1"); + bindoptions.add("0.0.0.0"); + for (String netaddr : getHostAddresses()) { + bindoptions.add(netaddr); + } + String[] bostring = new String[bindoptions.size()]; + bindoptions.toArray(bostring); + bindBox = new JComboBox(bostring); + add(bindBox); + + JButton addButton = new JButton("Start New Server"); + add(addButton); + addButton.addActionListener(e -> { + try { + String className = (String) servBox.getSelectedItem(); + long portLong = Long.parseLong(portSpinner.getValue().toString()); + System.out.println(portLong); + int port = (int) portLong; + String bindaddress = (String) bindBox.getSelectedItem(); + Server server = (Server) Class.forName("info.istlab.ServerTester." + className) + .getConstructor(int.class, String.class).newInstance(port, bindaddress); + host.addPanel(new ServerPanel(server, host)); + } catch (Exception e1) { + e1.printStackTrace(); + } + }); + } + + public ArrayList getHostAddresses() { + ArrayList addresses = new ArrayList(); + Enumeration interfaces; + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface ni = (NetworkInterface) interfaces.nextElement(); + java.util.List interfaceAddresses = ni.getInterfaceAddresses(); + for (InterfaceAddress interfaceAddress : interfaceAddresses) { + InetAddress address = interfaceAddress.getAddress(); + if (address.isLoopbackAddress()) { + continue; + } + if (interfaceAddress.getNetworkPrefixLength() > 32) { + continue; + } + int prefixLength = interfaceAddress.getNetworkPrefixLength(); + int subnetMask = 0xffffffff << (32 - prefixLength); + + // サブネットマスクを計算して表示 + String subnetMaskString = String.format("%d.%d.%d.%d", + (subnetMask >> 24 & 0xff), + (subnetMask >> 16 & 0xff), + (subnetMask >> 8 & 0xff), + (subnetMask & 0xff)); + + // ネットワークアドレスの計算 + int ipInt = inetAddressToInt(address); + int networkInt = ipInt & subnetMask; + + String networkAddressString = String.format("%d.%d.%d.%d", + (networkInt >> 24) & 0xff, + (networkInt >> 16) & 0xff, + (networkInt >> 8) & 0xff, + networkInt & 0xff); + + // 結果を表示 + System.out.println("Interface: " + ni.getDisplayName()); + System.out.println("IP Address: " + address.getHostAddress()); + System.out.println("Subnet Mask: " + subnetMaskString); + System.out.println("Network Address: " + networkAddressString); + addresses.add(address.getHostAddress()); + } + } + } catch (SocketException e1) { + e1.printStackTrace(); + } + return addresses; + } + + // IPアドレスを整数に変換するヘルパーメソッド + private static int inetAddressToInt(InetAddress inetAddress) { + byte[] addressBytes = inetAddress.getAddress(); + return ((addressBytes[0] & 0xff) << 24) | + ((addressBytes[1] & 0xff) << 16) | + ((addressBytes[2] & 0xff) << 8) | + (addressBytes[3] & 0xff); + } +} diff --git a/src/main/java/info/istlab/ServerTester/App.java b/src/main/java/info/istlab/ServerTester/App.java index e79d20d..86bd8cd 100644 --- a/src/main/java/info/istlab/ServerTester/App.java +++ b/src/main/java/info/istlab/ServerTester/App.java @@ -1,7 +1,6 @@ package info.istlab.ServerTester; -public class App -{ +public class App { public static boolean isWindows; public static String userhome; public static String userdir; @@ -13,33 +12,32 @@ userdir = System.getProperty("user.dir"); } - public static void main( String[] args ) - { + public static void main(String[] args) { Host myhost = new Host(); WebServer web = new WebServer(8081); - myhost.addPanel(new ServerPanel(web)); + myhost.addPanel(new ServerPanel(web, myhost)); - WebServer web2 = new WebServer(8081,"127.0.0.1"); - myhost.addPanel(new ServerPanel(web2)); + WebServer web2 = new WebServer(8081, "0.0.0.0"); + myhost.addPanel(new ServerPanel(web2, myhost)); // WebServer web3 = new WebServer(8081,"127.0.0.1"); // myhost.addPanel(new ServerPanel(web3)); TimeServer time = new TimeServer(); - myhost.addPanel(new ServerPanel(time)); + myhost.addPanel(new ServerPanel(time, myhost)); ThreadTimeServer time2 = new ThreadTimeServer(10999); - myhost.addPanel(new ServerPanel(time2)); + myhost.addPanel(new ServerPanel(time2, myhost)); EchoServer echo = new EchoServer(10008); - myhost.addPanel(new ServerPanel(echo)); + myhost.addPanel(new ServerPanel(echo, myhost)); ThreadEchoServer techo = new ThreadEchoServer(10018); - myhost.addPanel(new ServerPanel(techo)); + myhost.addPanel(new ServerPanel(techo, myhost)); WhiteBoardServer wb = new WhiteBoardServer(11111); - myhost.addPanel(new ServerPanel(wb)); - + myhost.addPanel(new ServerPanel(wb, myhost)); + } } diff --git a/src/main/java/info/istlab/ServerTester/EchoServer.java b/src/main/java/info/istlab/ServerTester/EchoServer.java index ccce1b6..bc11d65 100644 --- a/src/main/java/info/istlab/ServerTester/EchoServer.java +++ b/src/main/java/info/istlab/ServerTester/EchoServer.java @@ -44,4 +44,7 @@ } } } + public static void main(String[] args) { + invokeMain(args, "EchoServer"); + } } diff --git a/src/main/java/info/istlab/ServerTester/Host.java b/src/main/java/info/istlab/ServerTester/Host.java index f28b418..fa3f4c6 100644 --- a/src/main/java/info/istlab/ServerTester/Host.java +++ b/src/main/java/info/istlab/ServerTester/Host.java @@ -1,22 +1,45 @@ package info.istlab.ServerTester; +import java.awt.BorderLayout; + +import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; import javax.swing.JPanel; public class Host extends JFrame { - public static Host host; + public static Host mainhost; public JPanel mainPanel; + public Host() { setTitle("Host"); setSize(300, 200); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); - + setupMenu(); mainPanel = new JPanel(); mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); add(mainPanel); - host = this; + + JPanel addPanel = new AddPanel(this); + addPanel.setBorder(BorderFactory.createTitledBorder("Start New Server (Class, Port, Bind address)")); + add(addPanel, BorderLayout.NORTH); + mainhost = this; + } + + private void setupMenu() { + JMenuBar menuBar = new JMenuBar(); + setJMenuBar(menuBar); + JMenu menu = new JMenu("Menu"); + menuBar.add(menu); + JMenuItem exitItem = new JMenuItem("Exit"); + menu.add(exitItem); + exitItem.addActionListener(e -> { + System.exit(0); + }); } public void addPanel(JPanel panel) { diff --git a/src/main/java/info/istlab/ServerTester/NetworkMaskExample.java b/src/main/java/info/istlab/ServerTester/NetworkMaskExample.java new file mode 100644 index 0000000..c4db161 --- /dev/null +++ b/src/main/java/info/istlab/ServerTester/NetworkMaskExample.java @@ -0,0 +1,41 @@ +package info.istlab.ServerTester; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; + +public class NetworkMaskExample { + public static void main(String[] args) { + try { + // ローカルホストのInetAddressオブジェクトを取得 + InetAddress localHost = InetAddress.getLocalHost(); + + // ネットワークインターフェースを取得 + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost); + + if (networkInterface != null) { + // IPアドレスを取得 + String hostAddress = localHost.getHostAddress(); + + // ネットワークマスクの計算 + int prefixLength = networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength(); + int subnetMask = 0xffffffff << (32 - prefixLength); + + // サブネットマスクを計算して表示 + String subnetMaskString = String.format("%d.%d.%d.%d", + (subnetMask >> 24 & 0xff), + (subnetMask >> 16 & 0xff), + (subnetMask >> 8 & 0xff), + (subnetMask & 0xff)); + + System.out.println("IP Address: " + hostAddress); + System.out.println("Subnet Mask: " + subnetMaskString); + } else { + System.out.println("Network Interface for the given address is not found."); + } + } catch (UnknownHostException | SocketException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/info/istlab/ServerTester/Server.java b/src/main/java/info/istlab/ServerTester/Server.java index c46c676..4ff6769 100644 --- a/src/main/java/info/istlab/ServerTester/Server.java +++ b/src/main/java/info/istlab/ServerTester/Server.java @@ -1,15 +1,37 @@ 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; + public static void invokeMain(String[] args, String className) { + try { + if (args.length == 0) { + Server server = (Server) Class.forName("info.istlab.ServerTester." + className) + .getConstructor().newInstance(); + } else if (args.length == 1) { + Server server = (Server) Class.forName("info.istlab.ServerTester." + className) + .getConstructor(int.class).newInstance(Integer.parseInt(args[0])); + } else if (args.length == 2) { + Server server = (Server) 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 Server(int port, String bindaddress) { expectedPort = port; expectedAddress = bindaddress; @@ -75,6 +97,8 @@ serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(expectedAddress, expectedPort)); start(); + } catch (BindException bex){ + JOptionPane.showMessageDialog(null, "ポート "+expectedPort+" とバインドアドレス "+expectedAddress+" の組み合わせは使用されています。\n既存のサービスを停止するか、ポート番号/バインドアドレスを変更してください。", "エラー", JOptionPane.ERROR_MESSAGE); } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/java/info/istlab/ServerTester/ServerPanel.java b/src/main/java/info/istlab/ServerTester/ServerPanel.java index a3dbecb..bb0225d 100644 --- a/src/main/java/info/istlab/ServerTester/ServerPanel.java +++ b/src/main/java/info/istlab/ServerTester/ServerPanel.java @@ -1,6 +1,10 @@ package info.istlab.ServerTester; +import java.awt.Color; import java.awt.Desktop; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -11,6 +15,7 @@ public class ServerPanel extends JPanel implements Runnable { + Host host; Server server; String name; @@ -19,16 +24,19 @@ JLabel statusLabel; JButton stopButton; Thread thread; + JButton delButton; /** * Create the panel. */ - public ServerPanel(Server _server) { + public ServerPanel(Server _server, Host _host) { server = _server; + host = _host; name = _server.getClass().getName(); // remove package name name = name.substring(name.lastIndexOf('.') + 1); + JLabel lblNewLabel = new JLabel(name); add(lblNewLabel); @@ -48,8 +56,19 @@ } else { server.close(); } + repaint(); + host.pack(); }); + delButton = new JButton("Delete"); + delButton.setEnabled(false); + delButton.addActionListener(e -> { + server.close(); + Host.mainhost.mainPanel.remove(this); + Host.mainhost.pack(); + }); + add(delButton); + JButton clientButton = new JButton("Client"); add(clientButton); clientButton.addActionListener(e -> { @@ -83,18 +102,50 @@ addressLabel.setText(server.getExpectedAddress()); statusLabel.setText("Closed (Bind Failed?)"); stopButton.setText("Restart"); - } else { - portLabel.setText(String.valueOf(server.getPort())); - addressLabel.setText(server.getBindAddress()); + delButton.setEnabled(true); + } else if (server.thread != null) { + portLabel.setText(String.valueOf(server.getExpectedPort())); + addressLabel.setText(server.getExpectedAddress()); statusLabel.setText("Running"); stopButton.setText("Stop"); + delButton.setEnabled(false); } - Host.host.pack(); + try { - Thread.sleep(1000); + Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + Color color1 = Color.yellow; + Color color2 = Color.orange; + if (server.isClosed()){ + + } else if (server.thread != null){ + color1 = Color.cyan; + color2 = new Color(100,100,255); + } + + // Graphics2D オブジェクトを取得 + Graphics2D g2d = (Graphics2D) g; + + // パネルの幅と高さを取得 + int width = getWidth(); + int height = getHeight(); + + // グラデーションを設定(左上から右下にかけて) + GradientPaint gradientPaint = new GradientPaint(width/4, 0, color1, width, height, color2); + + // グラデーションで塗りつぶす + g2d.setPaint(gradientPaint); + g2d.fillRect(0, 0, width, height); + + g2d.setColor(Color.lightGray); + g2d.drawRect(0,0,width-1,height-1); + + } } diff --git a/src/main/java/info/istlab/ServerTester/ThreadEchoServer.java b/src/main/java/info/istlab/ServerTester/ThreadEchoServer.java index d03f219..dddfba2 100644 --- a/src/main/java/info/istlab/ServerTester/ThreadEchoServer.java +++ b/src/main/java/info/istlab/ServerTester/ThreadEchoServer.java @@ -38,6 +38,9 @@ } } } + public static void main(String[] args) { + invokeMain(args, "ThreadEchoServer"); + } } class RequestHandler4TES implements Runnable { diff --git a/src/main/java/info/istlab/ServerTester/ThreadTimeServer.java b/src/main/java/info/istlab/ServerTester/ThreadTimeServer.java index 726ca29..971718f 100644 --- a/src/main/java/info/istlab/ServerTester/ThreadTimeServer.java +++ b/src/main/java/info/istlab/ServerTester/ThreadTimeServer.java @@ -1,28 +1,20 @@ package info.istlab.ServerTester; -// 時刻を答えるサーバプログラムThreadTimeServer.java -// このプログラムはポート番号9999番で動作するサーバです -// クライアントから接続がきたら、一方的に時刻を返します -// このプログラムを停止させるにはコントロールCを入力してください -// 使い方: java ThreadTimeServer - -// ライブラリの利用 import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.util.Date; // TimeServerクラス -class ThreadTimeServer extends Server { - Thread thread; +public class ThreadTimeServer extends Server { - ThreadTimeServer() { + public ThreadTimeServer() { this(9999); } - ThreadTimeServer(int port) { + public ThreadTimeServer(int port) { this(port, "127.0.0.1"); } - ThreadTimeServer(int port, String address) { + public ThreadTimeServer(int port, String address) { super(port, address); start(); } @@ -45,6 +37,9 @@ } } } + public static void main(String[] args) { + invokeMain(args, "ThreadTimeServer"); + } } class RequestHandler4TTS implements Runnable { diff --git a/src/main/java/info/istlab/ServerTester/TimeServer.java b/src/main/java/info/istlab/ServerTester/TimeServer.java index 9ec189b..96fe99e 100644 --- a/src/main/java/info/istlab/ServerTester/TimeServer.java +++ b/src/main/java/info/istlab/ServerTester/TimeServer.java @@ -56,4 +56,8 @@ } } } + + public static void main(String[] args) { + invokeMain(args, "TimeServer"); + } } diff --git a/src/main/java/info/istlab/ServerTester/WebServer.java b/src/main/java/info/istlab/ServerTester/WebServer.java index 254bf5d..007ef8d 100644 --- a/src/main/java/info/istlab/ServerTester/WebServer.java +++ b/src/main/java/info/istlab/ServerTester/WebServer.java @@ -15,20 +15,15 @@ public class WebServer extends Server { public WebServer() { - super(80, "0.0.0.0"); - // handleRequest(); - start(); + this(80, "127.0.0.1"); } public WebServer(int port) { - super(port, "0.0.0.0"); - // handleRequest(); - start(); + this(port, "127.0.0.1"); } public WebServer(int port, String bindaddress) { super(port, bindaddress); - // handleRequest(); start(); } @@ -81,6 +76,9 @@ } } } + public static void main(String[] args) { + invokeMain(args, "WebServer"); + } } class RequestHandler implements Runnable { diff --git a/src/main/java/info/istlab/ServerTester/WhiteBoardClient.java b/src/main/java/info/istlab/ServerTester/WhiteBoardClient.java index d9264f0..229957b 100644 --- a/src/main/java/info/istlab/ServerTester/WhiteBoardClient.java +++ b/src/main/java/info/istlab/ServerTester/WhiteBoardClient.java @@ -19,8 +19,8 @@ public class WhiteBoardClient extends JPanel implements MouseListener, MouseMotionListener, Runnable { private static final long serialVersionUID = 1L; - private static final int PORT = 11111; - private static final String ADDRESS = "127.0.0.1"; + // private static final int PORT = 11111; + // private static final String ADDRESS = "127.0.0.1"; JFrame frame; ArrayList tmpStroke = new ArrayList(); CopyOnWriteArrayList points = new CopyOnWriteArrayList(); diff --git a/src/main/java/info/istlab/ServerTester/WhiteBoardServer.java b/src/main/java/info/istlab/ServerTester/WhiteBoardServer.java index 5b815fd..57772a0 100644 --- a/src/main/java/info/istlab/ServerTester/WhiteBoardServer.java +++ b/src/main/java/info/istlab/ServerTester/WhiteBoardServer.java @@ -51,7 +51,9 @@ } } } - + public static void main(String[] args) { + invokeMain(args, "WhiteBoardServer"); + } } class RequestHandler4WB implements Runnable {