所以我在桌面应用程序中使用Socket和ServerSocket的TCP / IP服务器/客户端模型(一种可以在网络中播放的游戏)。
我需要获取服务器的远程IP地址,以便客户端应用程序可以在打开的特定端口的已打开的服务器应用程序上连接到它。
public class ServerConnection {
private int PORT = 8100;
private ServerSocket serverSocket = null;
public void create() throws IOException {
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost", PORT));
}
public void close() throws IOException {
serverSocket.close();
}
public ClientConnection acceptRequest() throws IOException {
Socket socket = serverSocket.accept();
return new ClientConnection(socket);
}
public ServerConnection() throws IOException {
}
}
public class ClientConnection {
private String adress = "127.0.0.1";
private int PORT = 8100;
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
public ClientConnection() {
}
public ClientConnection(Socket socket) throws IOException {
this.socket = socket;
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
}
public void connect() throws UnknownHostException, IOException {
socket = new Socket(adress, PORT);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
}
public void close() throws IOException {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
socket = null;
}
}
public void send(String request) {
if (socket != null) {
out.println(request);
}
}
public String receive() throws IOException {
if (socket != null) {
return in.readLine();
}
return null;
}
}
它在localhost上运行良好,但我希望它能够在任何地方运行(服务器和客户端)。所以我需要一种方法让服务器找出它的当前远程IP,用户将通过一些通信线路(IM,E-mail等...)发送它,然后客户端将输入地址并连接到服务器。因此,一个应用程序可以充当服务器或客户端,因此不需要一个可以连续运行并为客户端提供服务的稳定服务器应用程序
答案 0 :(得分:1)
如果您的客户端和服务器位于同一网段,Zeroconf是一个非常有吸引力的零配置(井......)解决方案。你会发现一个Java实现with JmDNS
此外,从头开始实施稳定协议并非易事。如果不是出于教育目的,我建议依赖
之类的东西这些库为您提供了许多重要的功能,例如错误处理和并发(非阻塞调用)。
如果要从外部访问服务器,则无法绑定到“localhost”。请参阅ServerSocket.bind。您可以绑定到“null”并请求默认情况下通过ServerSocket.getInetAddress使用的网络适配器。
答案 1 :(得分:0)
您需要进行两项调整:
服务器套接字必须绑定到localhost之外的其他内容。通常,您使用new ServerSocket(port)
创建服务器套接字,而不指定主机名。这样,服务器套接字将在给定端口上侦听机器上的所有可用地址。如果将套接字绑定到“localhost”,则只能通过localhost访问它。那不是你想要的。创建服务器套接字后,您可以尝试使用SocketAddress
找出其serverSocket.getLocalSocketAddress()
。
客户端需要连接到创建/绑定服务器套接字时指定的地址。如果您创建了服务器套接字而未指定地址(即绑定到所有可用地址),则客户端可以连接到其中任何一个(通常是localhost +外部IP地址)。
服务器通常不需要知道他们的地址。它们只是绑定到<any address>:port
,客户端必须知道要连接的地址。