在简单的客户端/服务器程序失败

时间:2013-10-14 14:49:23

标签: java networking client

我有一个分布式应用程序,客户端连接到主服务器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);
        }
    }
}
}

1 个答案:

答案 0 :(得分:0)

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

话虽如此,您遇到的一个问题是处理“list”命令的客户端代码部分中的“ in.close(); ”行。正如Socket.getInputStream()的javadoc所述:

  

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

因此,在获取列表一次之后,您将无法再使用该套接字执行任何操作。