【发布时间】:2018-06-05 09:44:48
【问题描述】:
我正在用 java 开发一个聊天应用程序,但我遇到了部署问题。 即使我的应用程序在通过 IDE(IntelliJ 中的服务器和 Netbeans 中的客户端)执行时运行顺利,但当我尝试通过终端运行服务器时,服务器无法正常工作。不正确是指服务器正在接收来自用户的消息,但它没有回复。
例如,客户端执行的前三个步骤是:
- 登录
- 获取用户列表
- 获取组列表
即使服务器正在接收这些消息/请求,它也不会回复。
我将每个与服务器的连接分配给一个新线程,因为那是一个多客户端应用程序。
知道发生了什么吗?
这是终端中输出的示例图片:
然后服务器就挂在那里了。
服务器实现
这是启动服务器的代码。
public class ThreadedServer {
ServerSocket serverSocket;
private static Socket welcomeSocket = null;
public ThreadedServer() {
try {
serverSocket = new ServerSocket(ServerConfiguration.SERVER_PORT);
System.out.println("Server started");
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
try {
welcomeSocket = serverSocket.accept();
System.out.println("Connection accepted: " + welcomeSocket.getInetAddress() + ":" + welcomeSocket.getLocalPort());
Thread t = new Thread(new ClientConnection(welcomeSocket));
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
这是我处理收到的消息并发送我想要的消息的客户端连接类。
公共类 ClientConnection 实现 Runnable {
private final Socket clientSocket;
private DataInputStream dis;
private DataOutputStream dos;
private int sessionId;
private int userId;
private String username;
private ClientConnection self;
public ClientConnection(Socket client) {
this.clientSocket = client;
this.self = this;
}
public DataOutputStream getOutputStream() {
return dos;
}
@Override
public void run() {
System.out.println("Client Thread started!");
initializeDataStreams();
startListeningForMessages();
}
private void initializeDataStreams() {
try {
dis = new DataInputStream(clientSocket.getInputStream());
dos = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Server: Initialized Streams");
} catch (IOException ex) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void startListeningForMessages() {
new Thread(new Runnable() {
@Override
public void run() {
try {
String message;
while ((message = dis.readUTF()) != null) {
System.err.println("Recieved from client: " + message);
if (ServerConfiguration.LOG_COMMUNICATION_MESSAGES) {
System.out.println("client message string recieved \" "
+ message + " \"");
}
processMessage(message);
}
} catch (IOException ex) {
// 1) Remove the connection from the list of connections.
ConnectionManager.getInstance().removeConnection(self);
// 2) Inform database for logout time AND Error Messege!
DatabaseAction.logout(sessionId, "Unknown Error occurred");
}
}
}).start();
}
private void processMessage(String messege) {
Messege inbound = new Gson().fromJson(messege, Messege.class);
if (inbound.getType() == MessegeType.login) {
performLogin(inbound);
} else if (inbound.getType() == MessegeType.logout) {
performLogout(inbound);
} else if (inbound.getType() == MessegeType.simple_messege) {
sendMessege(inbound);
} else if (inbound.getType() == MessegeType.group_messege) {
sendGroupMessege(inbound);
} else if (inbound.getType() == MessegeType.get_all_users) {
getAllUsers();
} else if (inbound.getType() == MessegeType.get_groups_im_involved_in) {
getGroupsImInvolvedIn();
} else if (inbound.getType() == MessegeType.get_messeges_from_user) {
getMessegesFromUser(inbound);
} else if (inbound.getType() == MessegeType.get_messeges_from_group) {
getMessegesFromGroup(inbound);
} else if (inbound.getType() == MessegeType.create_new_group) {
createNewGroup(inbound);
}
}
private void sendGroupMessege(Messege inbound) {
new SendGroupMessegeAction(this, inbound);
}
public void close() {
try {
dis.close();
dos.close();
clientSocket.close();
} catch (IOException ex) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void performLogin(Messege messege) {
LoginAction la = new LoginAction(messege.getUser(), messege, this);
this.username = messege.getUser();
this.sessionId = la.getSessionId();
this.userId = la.getUserId();
}
private void performLogout(Messege messege) {
new LogoutAction(this, messege);
}
public void sendMessege(Messege messege) {
new SendSimpleMessegeAction(this, messege);
}
public int getSessionId() {
return sessionId;
}
public int getUserId() {
return userId;
}
public String getUsername() {
return username;
}
private void getAllUsers() {
try {
System.out.println("Sending all users to client " + username);
UsersObject uo = DatabaseAction.getAllUsers(userId);
GetAllUsersMessege gaum = new GetAllUsersMessege(uo.getUsernames(), uo.areOnline(), uo.getHasSentMessegesThatAreUnread());
Messege m = new Messege("", MessegeType.get_all_users, new Gson().toJson(gaum));
System.out.println("Sent from server: " + new Gson().toJson(m));
dos.writeUTF(new Gson().toJson(m));
dos.flush();
} catch (IOException ex) {
Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
这是从客户端
到服务器的连接public class ServerConnection {
DataInputStream dis;
static DataOutputStream dos;
Socket socket;
public static ServerConnection instance;
public static ServerConnection getInstance() {
if (instance == null) {
instance = new ServerConnection();
}
return instance;
}
private ServerConnection() {
initializeConnection();
startListeningThread();
}
private void initializeConnection() {
try {
socket = new Socket(MyStatics.server_address, 3333);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
System.out.println("Client: Connection Initialized");
} catch (IOException ex) {
Logger.getLogger(ServerConnection.class
.getName()).log(Level.SEVERE, null, ex);
}
}
private void startListeningThread() {
new Thread(new Runnable() {
@Override
public void run() {
try {
String line = "";
while (!socket.isClosed() && (line = dis.readUTF()) != null) {
System.out.println("Recieved from Server: " + line);
Messege m = new Gson().fromJson(line, Messege.class);
processMessege(m);
}
} catch (IOException ex) {
// Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex);
if (!ex.getMessage().equals("Socket closed")) {
`enter code here`Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}).start();
}
private void processMessege(Messege m) {
if (m.getType() == MessegeType.get_all_users) {
GetAllUsersMessege gaum = new Gson().fromJson(m.getEnv(), GetAllUsersMessege.class);
MainWindow.usersData = gaum.getUsers();
MainWindow.usersOnline = gaum.getOnline();
MainWindow.usersWhoSentSomething = gaum.getHasSentMessegesThatAreUnread();
MainWindow.changeData();
} else if (m.getType() == MessegeType.get_groups_im_involved_in) {
GetGroupsImInvolvedInMessege ggiiim = new Gson().fromJson(m.getEnv(), GetGroupsImInvolvedInMessege.class);
MainWindow.groupsData = ggiiim.getGroups();
MainWindow.changeData();
} else if (m.getType() == MessegeType.simple_messege) {
SimpleMessege sm = new Gson().fromJson(m.getEnv(), SimpleMessege.class);
MainWindow.informThatMessegeIsRecieved(m.getUser());
System.out.println("Recieved simple messege");
for (ChatBox chatBox : MyInstances.chatBoxes) {
if (chatBox.getTo().equals(m.getUser())) {
System.out.println("Chatbox was found");
chatBox.appendRecievedMessege(sm.getMessege());
}
}
...
...
}
}
编辑:我添加了代码 sn-ps。
【问题讨论】:
-
如果您能分享负责的代码将会很有帮助。如果没有关于您的服务器如何处理连接的确切方式,我们将无法为您提供适当的帮助。
标签: java multithreading sockets command-line