Java 在简单的客户端/服务器程序中失败
我有一个分布式应用程序,其中客户端连接到主服务器M以询问可用服务器的列表。M支持3种操作: 1) 将新服务器添加到列表中, 2) 从列表中删除服务器, 3) 向客户提供完整的列表。 到目前为止,我已经在本地机器上解决了这个问题,但我的客户在收到一个列表响应后停了下来。我做错了什么?守则如下:Java 在简单的客户端/服务器程序中失败,java,networking,client,Java,Networking,Client,我有一个分布式应用程序,其中客户端连接到主服务器M以询问可用服务器的列表。M支持3种操作: 1) 将新服务器添加到列表中, 2) 从列表中删除服务器, 3) 向客户提供完整的列表。 到目前为止,我已经在本地机器上解决了这个问题,但我的客户在收到一个列表响应后停了下来。我做错了什么?守则如下: // The client code. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre
// 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);
}
}
}
}
//客户端代码。
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.PrintWriter;
导入java.net.Socket;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Scanner;
公共类MainDummyClientApp{
公共静态最终int端口=1633;
公共静态最终字符串域=“127.0.0.1”;
公共静态最终字符串CMD_LIST=“LIST”;
公共静态最终字符串CMD\u HELLO\u IM\u SERVER=“HELLO from SERVER”;
public static final String CMD_BYE_FROM_SERVER=“byebye master”;
公共静态void main(字符串[]args){
列表套接字=新的ArrayList();
扫描仪=新的扫描仪(System.in);
Map Map=newhashmap();
对于(;;){
系统输出打印(“>”);
String cmd=scanner.nextLine();
字符串[]subs=cmd.split(“”);
if(subs[0].equals(“connect”)){
//连接
套接字s=null;
试一试{
s=新插座(SUB[2],端口);
字符串名称=subs[1];
地图放置(名称s);
插座。添加(s);
}捕获(IOE异常){
e、 printStackTrace(System.err);
}
}else if(subs[0].equals(“list”)){
//名单
试一试{
PrintWriter out=新的PrintWriter(
get(subs[1]).getOutputStream();
out.println(命令列表);
out.flush();
BufferedReader in=null;
in=新的缓冲读取器(
新的InputStreamReader(
get(subs[1]).getInputStream()
)
);
弦线;
而((line=in.readLine())!=null){
系统输出打印项次(行);
}
in.close();
}捕获(例外e){
e、 printStackTrace(System.err);
}
}else if(subs[0]。等于(“敲打”)){
//敲打
套接字s=map.get(subs[1]);
试一试{
PrintWriter out=新的PrintWriter(s.getOutputStream());
println(CMD\u HELLO\u IM\u服务器);
out.flush();
}捕获(IOE异常){
e、 printStackTrace(System.err);
}
}else if(subs[0].equals(“bye”)){
//再见
套接字s=map.get(subs[1]);
试一试{
PrintWriter out=新的PrintWriter(s.getOutputStream());
out.println(来自服务器的CMD\u BYE\u);
out.flush();
}捕获(IOE异常){
e、 printStackTrace(System.err);
}
}
}
}
//主服务器代码。
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.PrintWriter;
导入java.net.InetAddress;
导入java.net.ServerSocket;
导入java.net.Socket;
导入java.util.HashSet;
导入java.util.Set;
导入java.util.concurrent.Semaphore;
公共类TUMasterServerMain扩展线程{
公共静态布尔调试=true;
公共静态最终int端口=1633;
公共静态最终字符串CMD_LIST=“LIST”;
公共静态最终字符串CMD\u HELLO\u IM\u SERVER=“HELLO from SERVER”;
public static final String CMD_BYE_FROM_SERVER=“byebye master”;
私有静态ServerSocket ServerSocket;
私有静态集serverSet=newhashset();
私有静态最终信号量互斥=新信号量(1,true);
专用套接字客户端;
公用TUMasterServerMain(套接字客户端){
this.client=client;
}
@凌驾
公开募捐{
BufferedReader br=null;
PrintWriter pw=null;
试一试{
br=新的BufferedReader(新的InputStreamReader(client.getInputStream());
pw=新的PrintWriter(client.getOutputStream(),true);
如果(调试){
System.out.println(“[DEBUG]在服务器循环之前”);
}
对于(;;){
字符串cmd=br.readLine();
如果(调试){
System.out.println(“[DEBUG]收到命令:”+cmd);
}
如果(cmd==null){
如果(调试){
System.out.println(“[DEBUG]服务器线程返回”);
}
br.close();
关闭();
返回;
}
如果(命令等于(命令列表)){
mutex.acquireUnterruptibly();
pw.println(命令列表);
用于(InetAddress服务器地址:服务器集){
write(serverAddress.getHostName()+'\n');
}
pw.flush();
mutex.release();
如果(调试){
System.out.println(“[DEBUG]列出所有服务器:”+
serverSet.size()+“服务器已启动。”);
}
}else if(cmd.equals(cmd\u HELLO\u IM\u SERVER)){
mutex.acquireUnterruptibly();
InetAddress=client.getInetAddress();
serverSet.add(地址);
mutex.release();
如果(调试){
System.out.println(“[DEBUG]添加了新服务器:”+
address.getHostAddress());
}
}else if(cmd.equals(cmd_BYE_FROM_SERVER)){
mutex.acquireUnterruptibly();
InetAddress=client.getInetAddress();
if(serverSet.remove(地址)){