【发布时间】:2017-03-06 06:06:44
【问题描述】:
所以我一直在进行简单的聊天,而不是有一个服务器和一堆连接到它们的客户端。在客户端,我有类 ConnectionManager 来管理创建套接字等。这是它的核心方法:
public class ConnectionManager {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
public ConnectionManager(String URL, int port){
tryConnectToServer(URL, port);
}
public BufferedReader getReader() {
return reader;
}
public PrintWriter getWriter() {
return writer;
}
private void tryConnectToServer(String ip, int servSocket) {
try{
socket = new Socket(ip, servSocket);
writer = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
}
catch (IOException ex){
System.out.println("Unable to connect to specified server. Code pink");
ex.printStackTrace();
}
}
连接管理器对象是 ChatGUI 的一部分。 ChatGUI 的字段 writer 和 reader 是从 CM 获取和设置的,以便将 writer 与 ChatGUI 的 JTextField (msgInput) 一起传递给 SendButtonListener:
private void addSendButton() {
JButton sendButton = new JButton("Send");
sendButton.addActionListener(new SendButtonActionListener(writer, msgInput));
panel.add(sendButton);
panel.add(this.msgArea);
}
然后,actionPerformed 方法会:
public class SendButtonActionListener implements ActionListener{
private PrintWriter writer;
private JTextField msgInput;
public SendButtonActionListener(PrintWriter pr, JTextField mi){
writer = pr;
msgInput = mi;
}
public void actionPerformed(ActionEvent event){
writer.println(msgInput.getText());
System.out.println("Sending: " + msgInput.getText());
flushMessageInputField();
}
private void flushMessageInputField(){
msgInput.setText("");
}
}
另一方面,在服务器端我有这个:
try{
this.servSocket = new ServerSocket(port);
System.out.println("Server socket established");
}
catch (IOException ex){
System.out.println("Unable to establish server socket. Code pink \n");
ex.printStackTrace();
}
在上述之后是这样的:
public void waitForClients(){
System.out.println("The gates has been opened...");
while (true){
try {
Socket client = servSocket.accept();
processClient(client);
}
catch (IOException ex){
ex.printStackTrace();
}
}
}
private void processClient(Socket client){
writers.add(getClientWriter(client));
startUpdateFrom(client);
System.out.println("New client connected: " + client.getPort());
}
private PrintWriter getClientWriter(Socket client){
try{
return new PrintWriter(client.getOutputStream());
}
catch (Exception ex){
ex.printStackTrace();
}
return null;
}
最后,一个新线程开始监听来自该客户端的任何新消息:
private void startUpdateFrom(Socket client){
new Thread(
new WaitAndSendToAllFrom(client))
.start();
}
这是:
public class WaitAndSendToAllFrom implements Runnable{
BufferedReader reader;
public WaitAndSendToAllFrom(Socket clientSocket){
try{
reader = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
}
catch (IOException ex){
ex.printStackTrace();
}
}
public void run(){
try{
String message;
System.out.println("Thread: waiting for messages to send...");
while (true){
message = reader.readLine();
while (message != null){
System.out.println("Server: Sending message: " + message);
sendToAll(message);
}
}
}
catch (IOException ex){
ex.printStackTrace();
}
}
private void sendToAll(String message){
List<PrintWriter> writers = ServerClientConnector.getWriters();
for (PrintWriter pr : writers){
pr.println(message + "\n");
pr.flush();
}
}
}
循环到达“线程:等待消息发送...”,但不再进一步,reader.readLine() 返回 null(使用 sysout :) 检查)。我试图调试它,但我在编程方面没有那么丰富的经验,尤其是调试两个相互协作的独立代码。我已经看了 3 天了,我严重卡在这里。
【问题讨论】:
-
你能发布从客户端发送消息的代码吗?顺便说一句,您在
WaitAndSendToAllFrom->run->while(message != null)中有一个无限循环 - while.loop 中的消息不可能更改,因此它将永远循环和循环(即使这不是您要求的问题,也可能是下一个一)。 -
我已经编辑了这篇文章,写的不多,但我相信这就是所需要的:)。提前解决其他错误/错误 - 我知道代码需要稍微更改和重构,但现在我专注于那些该死的套接字/读取器/写入器:)。
标签: java sockets connection