如何从服务器端的 LISTEN 状态释放端口
How to release a port from the state LISTEN at the server side
我是 JAVA 中的套接字新手。最近,我正在尝试构建一个服务器-客户端程序,客户端可以从服务器端的字典中搜索单词,服务器将 return 单词的定义发送给客户端。服务器端代码如下:
public class DictionaryServer {
private static int port;
private static String dicFile;
static Map<String, String> dictionary = new HashMap<String, String>();
int userCounter = 0;
public static void main(String[] args) {
//check if starting the server in valid format
if (args.length != 2) {
System.err.println("Invalid format to start DictionaryServer");
System.err.println("Usage: java DictionaryServer <port number> <the name of dictionary>");
System.exit(1);
}
port = Integer.parseInt(args[0]);
dicFile = args[1];
try{
System.out.println("IP: " + InetAddress.getLocalHost());
System.out.println("port: " + port);
}
catch(UnknownHostException e){
e.printStackTrace();
}
DictionaryServer s = new DictionaryServer();
s.server(port, dicFile);
}
public void server(int port, String dicFile) {
ServerSocketFactory serverSocket = ServerSocketFactory.getDefault();
try(ServerSocket server = serverSocket.createServerSocket(port)){
System.out.println("Server IP: " + server.getInetAddress());
System.out.println("Listening for client connections...");
while(true){
Socket client = server.accept();
System.out.println("Client \"" + client.getRemoteSocketAddress().toString()
+ "\""+ " is connecting.");
Thread t = new Thread(() -> service(client, dicFile));
t.start();
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
public void service(Socket client, String dicFile){
try(Socket clientSocket = client){
// Input and Output stream of the client
DataInputStream input = new DataInputStream(
clientSocket.getInputStream());
DataOutputStream output = new DataOutputStream(
clientSocket.getOutputStream());
//check request
int action = input.readInt(); //1:add, 2:remove, 3:query
String word = input.readUTF();
//choose action
Dic d = new Dic(dicFile);
switch(action){
case 1: //add
String definition = input.readUTF();
output.writeUTF(d.add(word, definition, dicFile));
break;
case 2: //remove
output.writeUTF(d.remove(word, dicFile));
break;
case 3: //query
output.writeUTF(d.query(word, dicFile));
break;
}
}
catch(IOException e){
String message=e.getMessage();
System.out.println(message);
System.out.println();
}
}
当我尝试重新启动服务器程序时遇到错误:java.net.BindException:地址已在使用中(绑定失败)
比如我上次用4000端口执行服务器程序是成功的,但是如果我再用同样的端口执行服务器程序,就会出现异常。我在终端中通过 "lsof -i:4000" 检查了端口 4000 正在做什么,它告诉我:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 19683 Andy 7u IPv6 0x43e8f876eb74b731 0t0 TCP *:terabase (LISTEN)
有谁知道我该如何解决这个问题?谢谢!
你需要确定你的程序真的退出了,你还需要设置reuseAddress
。为此,您必须在不绑定的情况下创建服务器套接字,设置选项,然后通过三个不同的步骤绑定它:
ServerSocket server = serverSocketFactory.createServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(port));
我是 JAVA 中的套接字新手。最近,我正在尝试构建一个服务器-客户端程序,客户端可以从服务器端的字典中搜索单词,服务器将 return 单词的定义发送给客户端。服务器端代码如下:
public class DictionaryServer {
private static int port;
private static String dicFile;
static Map<String, String> dictionary = new HashMap<String, String>();
int userCounter = 0;
public static void main(String[] args) {
//check if starting the server in valid format
if (args.length != 2) {
System.err.println("Invalid format to start DictionaryServer");
System.err.println("Usage: java DictionaryServer <port number> <the name of dictionary>");
System.exit(1);
}
port = Integer.parseInt(args[0]);
dicFile = args[1];
try{
System.out.println("IP: " + InetAddress.getLocalHost());
System.out.println("port: " + port);
}
catch(UnknownHostException e){
e.printStackTrace();
}
DictionaryServer s = new DictionaryServer();
s.server(port, dicFile);
}
public void server(int port, String dicFile) {
ServerSocketFactory serverSocket = ServerSocketFactory.getDefault();
try(ServerSocket server = serverSocket.createServerSocket(port)){
System.out.println("Server IP: " + server.getInetAddress());
System.out.println("Listening for client connections...");
while(true){
Socket client = server.accept();
System.out.println("Client \"" + client.getRemoteSocketAddress().toString()
+ "\""+ " is connecting.");
Thread t = new Thread(() -> service(client, dicFile));
t.start();
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch(IOException e) {
e.printStackTrace();
}
}
public void service(Socket client, String dicFile){
try(Socket clientSocket = client){
// Input and Output stream of the client
DataInputStream input = new DataInputStream(
clientSocket.getInputStream());
DataOutputStream output = new DataOutputStream(
clientSocket.getOutputStream());
//check request
int action = input.readInt(); //1:add, 2:remove, 3:query
String word = input.readUTF();
//choose action
Dic d = new Dic(dicFile);
switch(action){
case 1: //add
String definition = input.readUTF();
output.writeUTF(d.add(word, definition, dicFile));
break;
case 2: //remove
output.writeUTF(d.remove(word, dicFile));
break;
case 3: //query
output.writeUTF(d.query(word, dicFile));
break;
}
}
catch(IOException e){
String message=e.getMessage();
System.out.println(message);
System.out.println();
}
}
当我尝试重新启动服务器程序时遇到错误:java.net.BindException:地址已在使用中(绑定失败)
比如我上次用4000端口执行服务器程序是成功的,但是如果我再用同样的端口执行服务器程序,就会出现异常。我在终端中通过 "lsof -i:4000" 检查了端口 4000 正在做什么,它告诉我:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 19683 Andy 7u IPv6 0x43e8f876eb74b731 0t0 TCP *:terabase (LISTEN)
有谁知道我该如何解决这个问题?谢谢!
你需要确定你的程序真的退出了,你还需要设置reuseAddress
。为此,您必须在不绑定的情况下创建服务器套接字,设置选项,然后通过三个不同的步骤绑定它:
ServerSocket server = serverSocketFactory.createServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(port));