我有一个分布式应用程序,客户端连接到主服务器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 :(得分:0)
如果您确实描述了您正在观察的意外错误或行为,那么回答会更容易。
话虽如此,您遇到的一个问题是处理“list”命令的客户端代码部分中的“ in.close(); ”行。正如Socket.getInputStream()的javadoc所述:
关闭返回的InputStream将关闭相关的套接字。
因此,在获取列表一次之后,您将无法再使用该套接字执行任何操作。