diff --git a/.vscode/launch.json b/.vscode/launch.json index 9f34117..1429a1b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,6 +6,13 @@ "configurations": [ { "type": "java", + "name": "ListNetworkInterfaces", + "request": "launch", + "mainClass": "info.istlab.ServerTester.ListNetworkInterfaces", + "projectName": "KisoServerTester" + }, + { + "type": "java", "name": "SimpleWebSocketServer", "request": "launch", "mainClass": "info.istlab.ServerTester.SimpleWebSocketServer", diff --git a/src/main/java/info/istlab/ServerTester/App.java b/src/main/java/info/istlab/ServerTester/App.java index c56ff05..0358bc6 100644 --- a/src/main/java/info/istlab/ServerTester/App.java +++ b/src/main/java/info/istlab/ServerTester/App.java @@ -1,6 +1,8 @@ package info.istlab.ServerTester; import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.NetworkInterface; public class App { public static boolean isWindows; @@ -8,6 +10,8 @@ public static String userdir; public static boolean isJAR = false; public static String ipAddr; + public static NetworkInterface primaryInterface; + public static InetAddress primaryInetAddr; static { String os = System.getProperty("os.name").toLowerCase(); @@ -21,6 +25,10 @@ String location = clazz.getProtectionDomain().getCodeSource().getLocation().getPath(); isJAR = location.endsWith(".jar"); + // ネットワークインタフェースの調査と選択 + primaryInterface = NetworkInterfaceSelector.getPrimaryInterface(); + primaryInetAddr = NetworkInterfaceSelector.getPrimaryInetAddr(primaryInterface); + Host myhost = new Host(); if (args.length > 0) { // 実行時の引数で Web とか Time とか指定された場合、動的にサーバを生成 diff --git a/src/main/java/info/istlab/ServerTester/Host.java b/src/main/java/info/istlab/ServerTester/Host.java index 90c1240..f4a1285 100644 --- a/src/main/java/info/istlab/ServerTester/Host.java +++ b/src/main/java/info/istlab/ServerTester/Host.java @@ -17,7 +17,7 @@ public MulticastReceiver multicastReceiver; public Host() { - setTitle("サーバ管理ウィンドウ"); + setTitle("サーバ管理ウィンドウ "+App.primaryInterface.getDisplayName() + " " + App.primaryInetAddr.getHostAddress()); setSize(300, 200); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { diff --git a/src/main/java/info/istlab/ServerTester/MulticastReceiver.java b/src/main/java/info/istlab/ServerTester/MulticastReceiver.java index 345e1a4..8b5f9f1 100644 --- a/src/main/java/info/istlab/ServerTester/MulticastReceiver.java +++ b/src/main/java/info/istlab/ServerTester/MulticastReceiver.java @@ -1,26 +1,36 @@ package info.istlab.ServerTester; import java.io.IOException; -import java.net.DatagramPacket; import java.net.InetAddress; -import java.net.MulticastSocket; -import java.net.SocketException; +import java.net.InetSocketAddress; +import java.net.StandardProtocolFamily; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; import java.util.Hashtable; public class MulticastReceiver implements Runnable { Thread thread; - MulticastSocket socket; + // MulticastSocket socket; MulticastSender sender; RemoteHostsWindow remoteHostsWindow; + DatagramChannel channel; // 受信したデータを IP アドレスをキーにして保存 Hashtable receivedData = new Hashtable(); public MulticastReceiver(int portNum) { try { - socket = new MulticastSocket(portNum); + // socket = new MulticastSocket(portNum); InetAddress group = InetAddress.getByName("224.0.0.1"); - socket.joinGroup(group); + + try { + channel = DatagramChannel.open(StandardProtocolFamily.INET); + channel.bind(new InetSocketAddress(portNum)); + channel.join(group, App.primaryInterface); + } catch (IOException e) { + e.printStackTrace(); + } + // socket.joinGroup(group); } catch (IOException e) { e.printStackTrace(); } @@ -31,33 +41,37 @@ } public void run() { + ByteBuffer buffer = ByteBuffer.allocate(1024); while (thread != null) { - byte[] buffer = new byte[1024]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + buffer.clear(); + InetSocketAddress senderAddr = null; try { - socket.receive(packet); - } catch (SocketException sx) { - thread = null; + senderAddr = (InetSocketAddress) channel.receive(buffer); } catch (IOException e) { e.printStackTrace(); } - if (!socket.isClosed() && packet != null) { - String addr = packet.getAddress().getHostAddress(); - String message = new String(packet.getData(), 0, packet.getLength()); + buffer.flip(); - receivedData.put(addr, message); + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + String message = new String(data); + String addr = senderAddr.getAddress().getHostAddress(); + receivedData.put(addr, message); - if (remoteHostsWindow != null) { - remoteHostsWindow.updateData(addr, message); - remoteHostsWindow.frame.pack(); - } + if (remoteHostsWindow != null) { + remoteHostsWindow.updateData(addr, message); + remoteHostsWindow.frame.pack(); } - // System.out.println(addr+"からの受信: " + message); } } public void stop() { - socket.close(); + try { + channel.close(); + } catch (IOException e) { + e.printStackTrace(); + } + // socket.close(); sender.stop(); remoteHostsWindow.frame.dispose(); remoteHostsWindow = null; diff --git a/src/main/java/info/istlab/ServerTester/NetworkInterfaceSelector.java b/src/main/java/info/istlab/ServerTester/NetworkInterfaceSelector.java new file mode 100644 index 0000000..8851e1d --- /dev/null +++ b/src/main/java/info/istlab/ServerTester/NetworkInterfaceSelector.java @@ -0,0 +1,94 @@ +package info.istlab.ServerTester; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +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 java.util.List; + +import javax.swing.JDialog; + +public class NetworkInterfaceSelector extends JDialog implements ActionListener { + + // 複数のIPv4アドレスを持つネットワークインターフェースがある場合、ユーザに選択させる。 + public static NetworkInterface getPrimaryInterface() { + ArrayList ipv4interfaces = getIPv4Interfaces(); + if (ipv4interfaces.size() == 1) { + return ipv4interfaces.get(0); + } else { + // 複数のインターフェースがある場合、ユーザに選択させる + NetworkInterface[] interfaces = new NetworkInterface[ipv4interfaces.size()]; + for (int i = 0; i < ipv4interfaces.size(); i++) { + interfaces[i] = ipv4interfaces.get(i); + } + // NetworkInterface selectedInterface = (NetworkInterface) + // JOptionPane.showInputDialog(null, "Select a network interface", "Select a + // network interface", JOptionPane.QUESTION_MESSAGE, null, interfaces, + // interfaces[0]); + // return selectedInterface; + return null; + } + } + + public NetworkInterfaceSelector() { + + } + + public static ArrayList getIPv4Interfaces() { + ArrayList ret = new ArrayList(); + try { + // 利用可能なネットワークインターフェースを取得 + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + + // 各インターフェースの情報を表示 + while (interfaces.hasMoreElements()) { + NetworkInterface networkInterface = interfaces.nextElement(); + + // インターフェース名と表示名を出力 + System.out.println("Name: " + networkInterface.getName()); + System.out.println("Display Name: " + networkInterface.getDisplayName()); + System.out.println("Up: " + networkInterface.isUp()); + System.out.println("Loopback: " + networkInterface.isLoopback()); + System.out.println("Virtual: " + networkInterface.isVirtual()); + System.out.println("Supports Multicast: " + networkInterface.supportsMulticast()); + // ループバックインターフェースは除外 + if (networkInterface.isLoopback()) { + continue; + } + // InterfaceAddress を取得して IPv4 アドレスを表示 + List addresses = networkInterface.getInterfaceAddresses(); + for (InterfaceAddress addr : addresses) { + InetAddress inetAddr = addr.getAddress(); + if (inetAddr instanceof java.net.Inet4Address) { // IPv4 アドレスのみ + System.out.println("IPv4 Address: " + inetAddr.getHostAddress()); + ret.add(networkInterface); + } + } + System.out.println("----------------------------------------------------"); + } + } catch (SocketException e) { + e.printStackTrace(); + } + return ret; + } + + @Override + public void actionPerformed(ActionEvent e) { + throw new UnsupportedOperationException("Unimplemented method 'actionPerformed'"); + } + + public static InetAddress getPrimaryInetAddr(NetworkInterface primaryInterface) { + List addresses = primaryInterface.getInterfaceAddresses(); + for (InterfaceAddress addr : addresses) { + InetAddress inetAddr = addr.getAddress(); + if (inetAddr instanceof java.net.Inet4Address) { // IPv4 アドレスのみ + return inetAddr; + } + } + return null; + } +} diff --git a/src/main/java/info/istlab/ServerTester/RemoteHostsWindow.java b/src/main/java/info/istlab/ServerTester/RemoteHostsWindow.java index 988e211..4512ccc 100644 --- a/src/main/java/info/istlab/ServerTester/RemoteHostsWindow.java +++ b/src/main/java/info/istlab/ServerTester/RemoteHostsWindow.java @@ -19,6 +19,7 @@ JTabbedPane tabbedPane; Hashtable panels = new Hashtable(); JFrame frame; + public RemoteHostsWindow(Hashtable receivedData) { frame = new JFrame(); frame.setTitle("Remote Hosts"); @@ -44,18 +45,19 @@ frame.setLocation(50, 400); frame.pack(); frame.setVisible(true); + } public void updateData(String addr, String value) { - RemoteHostPanel panel = panels.get(addr); - if (panel != null) { - panel.renewal(value); + RemoteHostPanel rhp = panels.get(addr); + if (rhp != null) { + rhp.renewal(value); tabbedPane.validate(); tabbedPane.repaint(); // System.out.println("Tab updated " + addr); // System.out.println(value); } else { - RemoteHostPanel rhp = new RemoteHostPanel(addr, value); + rhp = new RemoteHostPanel(addr, value); tabbedPane.add(addr, rhp); panels.put(addr, rhp); }