2013-10-14 33 views
0

我有一个分布式应用程序,其中客户端连接到主服务器M问可用服务器的列表。 -M支持3个操作: 1)新的服务器添加到列表中, 2)从列表中删除服务器, 3)给客户的完整列表。 到目前为止,我已经在本地机器上解决了这个问题,但是我的客户端在列表响应中停止。我在这里做错了什么?代码如下:失败在一个简单的客户端/服务器程序

// The client code. 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Scanner; 

public class MainDummyClientApp { 

public static final int PORT = 1633; 
public static final String DOMAIN = "127.0.0.1"; 
public static final String CMD_LIST = "list"; 
public static final String CMD_HELLO_IM_SERVER = "hello from server"; 
public static final String CMD_BYE_FROM_SERVER = "byebye master"; 

public static void main(String[] args) { 
    List<Socket> sockets = new ArrayList<Socket>(); 
    Scanner scanner = new Scanner(System.in); 
    Map<String, Socket> map = new HashMap<String, Socket>(); 

    for (;;) { 
     System.out.print("> "); 
     String cmd = scanner.nextLine(); 
     String[] subs = cmd.split(" "); 

     if (subs[0].equals("connect")) { 
      // connect <name> <url> 
      Socket s = null; 
      try { 
       s = new Socket(subs[2], PORT); 
       String name = subs[1]; 
       map.put(name, s); 
       sockets.add(s); 
      } catch (IOException e) { 
       e.printStackTrace(System.err); 
      } 
     } else if (subs[0].equals("list")) { 
      // list <name> 
      try { 
       PrintWriter out = new PrintWriter(
         map.get(subs[1]).getOutputStream()); 
       out.println(CMD_LIST); 
       out.flush(); 

       BufferedReader in = null; 

       in = new BufferedReader(
         new InputStreamReader(
          map.get(subs[1]).getInputStream() 
          ) 
         ); 

       String line; 

       while ((line = in.readLine()) != null) { 
        System.out.println(line); 
       } 

       in.close(); 
      } catch (Exception e) { 
       e.printStackTrace(System.err); 
      } 
     } else if (subs[0].equals("knock")) { 
      // knock <name> 
      Socket s = map.get(subs[1]); 
      try { 
       PrintWriter out = new PrintWriter(s.getOutputStream()); 
       out.println(CMD_HELLO_IM_SERVER); 
       out.flush(); 
      } catch (IOException e) { 
       e.printStackTrace(System.err); 
      } 
     } else if (subs[0].equals("bye")) { 
      // bye <name> 
      Socket s = map.get(subs[1]); 
      try { 
       PrintWriter out = new PrintWriter(s.getOutputStream()); 
       out.println(CMD_BYE_FROM_SERVER); 
       out.flush(); 
      } catch (IOException e) { 
       e.printStackTrace(System.err); 
      } 
     } 
    } 
} 
// The master server code. 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.HashSet; 
import java.util.Set; 
import java.util.concurrent.Semaphore; 

public class TUMasterServerMain extends Thread { 

public static boolean DEBUG = true; 
public static final int PORT = 1633; 
public static final String CMD_LIST = "list"; 
public static final String CMD_HELLO_IM_SERVER = "hello from server"; 
public static final String CMD_BYE_FROM_SERVER = "byebye master"; 

private static ServerSocket serverSocket; 

private static Set<InetAddress> serverSet = new HashSet<InetAddress>(); 

private static final Semaphore mutex = new Semaphore(1, true); 

private Socket client; 

public TUMasterServerMain(Socket client) { 
    this.client = client; 
} 

@Override 
public void run() { 
    BufferedReader br = null; 
    PrintWriter pw = null; 

    try { 
     br = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     pw = new PrintWriter(client.getOutputStream(), true); 

     if (DEBUG) { 
      System.out.println("[DEBUG] Before server loop."); 
     } 

     for (;;) { 
      String cmd = br.readLine(); 

      if (DEBUG) { 
       System.out.println("[DEBUG] Recieved command: " + cmd); 
      } 

      if (cmd == null) { 
       if (DEBUG) { 
        System.out.println("[DEBUG] Server thread returns."); 
       } 
       br.close(); 
       pw.close(); 
       return; 
      } 

      if (cmd.equals(CMD_LIST)) { 
       mutex.acquireUninterruptibly(); 
       pw.println(CMD_LIST); 
       for (InetAddress serverAddress : serverSet) { 
        pw.write(serverAddress.getHostName() + '\n'); 
       } 
       pw.flush(); 
       mutex.release(); 

       if (DEBUG) { 
        System.out.println("[DEBUG] Listing all the servers: " + 
          serverSet.size() + " server(s) are up."); 
       } 
      } else if (cmd.equals(CMD_HELLO_IM_SERVER)) { 
       mutex.acquireUninterruptibly(); 
       InetAddress address = client.getInetAddress(); 
       serverSet.add(address); 
       mutex.release(); 

       if (DEBUG) { 
        System.out.println("[DEBUG] New server added: " + 
          address.getHostAddress()); 
       } 
      } else if (cmd.equals(CMD_BYE_FROM_SERVER)) { 
       mutex.acquireUninterruptibly(); 
       InetAddress address = client.getInetAddress(); 
       if (serverSet.remove(address)) { 
        if (DEBUG) { 
         System.out.println("[DEBUG] Server removed: " + 
           address.getHostAddress()); 
        } 
       } 
       mutex.release(); 
       return; 
      } else { 
       throw new IllegalStateException("Should never get here!"); 
      } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(System.err); 
    } finally { 
     try { 
      br.close(); 
     } catch (IOException e) { 

     } 
     pw.close(); 
    } 
} 

public static void main(String[] args) { 
    // DEBUG = false; 
    try { 
     serverSocket = new ServerSocket(PORT); 
    } catch (IOException e) { 
     e.printStackTrace(System.err); 
     System.exit(-1); 
    } 

    for (;;) { 
     try { 
      Socket s = serverSocket.accept(); 
      new TUMasterServerMain(s).start(); 
      System.out.println("[SERVER]: Serving " + s.toString()); 
     } catch (IOException e) { 
      e.printStackTrace(System.err); 
     } 
    } 
} 
} 

回答

0

如果您实际描述了您正在观察的意外错误或行为,则回答会更容易。

这就是说,您拥有的一个问题是处理“list”命令的部分客户端代码中的行“in.close();”。正如javadoc中所述:Socket.getInputStream()

关闭返回的InputStream将关闭关联的套接字。

因此,越来越名单一次之后,您将无法再执行任何与插座。