2017-08-26 87 views
0

我是JAVA中的套接字的新手。最近,我正在尝试构建一个服务器端客户端程序,客户端可以从服务器端的字典中搜索单词,服务器将返回单词的定义给客户端。在服务器端的代码如下所示:如何在服务器端从状态LISTEN释放一个端口

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(); 
    } 
} 

我得到了一个错误stucked当我尝试重新启动serverprogram:java.net.BindException:地址已在使用中(绑定失败)

例如,上次我使用端口4000执行服务器程序并且它工作正常,但是如果我想再次使用同一个端口执行服务器程序,则会显示异常。我查了一下端口4000通过“lsof的-i:4000”在做终端,其告诉我:

COMMAND PID USER FD TYPE    DEVICE SIZE/OFF NODE NAME 
java 19683 Andy 7u IPv6 0x43e8f876eb74b731  0t0 TCP *:terabase (LISTEN) 

有谁知道如何解决这个问题?谢谢!

+1

一旦应用程序终止时,该端口最终由OS释放。它只需要一些时间。 – DyZ

+0

您必须杀死以前运行的服务器或使您的端口在运行时可以配置为不同 –

+0

感谢您的回复。但是我等了很久,但他们仍在听。我可以通过添加一些代码退出服务器程序来终止它们吗?唯一的办法是关闭我的Eclipse。 –

回答

1

您需要确保您的程序已经真正退出,并且您还需要设置reuseAddress。要做到这一点,你有没有绑定到创建服务器插座,设置选项,然后将它绑定,在三个不同的步骤:

ServerSocket server = serverSocketFactory.createServerSocket(); 
server.setReuseAddress(true); 
server.bind(new InetSocketAddress(port)); 
相关问题