Java:使用 AWT 按钮断开与聊天服务器的连接
Posted
技术标签:
【中文标题】Java:使用 AWT 按钮断开与聊天服务器的连接【英文标题】:Java: Using AWT button to disconnect from chat server 【发布时间】:2020-11-14 18:41:48 【问题描述】:我正在编写一个简单的多线程客户端/服务器聊天系统。项目要求规定:“连接仅在单击连接按钮时发生。断开按钮应断开连接。用户应能够随意连接、断开连接、重新连接。”基本上,我已经连接并运行了连接按钮。但是,当我尝试断开连接时,我陷入了无限循环,其中客户端(在命令行上)无限打印“Sock closed”,而服务器端无限打印“Message read: null”。这导致我查看我的所有 for(;;) 循环以某种方式关闭其中的连接,但是我无法弄清楚如何关闭这些循环中的连接。请帮忙,这是我的第一个套接字编程项目,我对这个超级难过!谢谢大家。
客户:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ClientFrame extends Frame
public ClientFrame()
setSize(500,500);
setTitle("Chat Client");
addWindowListener(new WindowAdapter()
public void windowClosing(WindowEvent We)
System.exit(0);
);
add(new ClientPanel(), BorderLayout.CENTER);
setVisible(true);
public static void main(String[] args)
new ClientFrame();
// end ClientFrame
class ClientPanel extends Panel implements ActionListener, Runnable
TextField tf;
TextArea ta;
List list;
Button connect, disconnect;
Socket socketToServer;
PrintWriter pw;
BufferedReader br;
Thread t;
String userName;
public ClientPanel()
setLayout(new BorderLayout());
tf = new TextField();
ta = new TextArea();
list = new List();
connect = new Button("Connect");
disconnect = new Button("Disconnect");
Panel bPanel = new Panel();
bPanel.add(connect);
disconnect.setEnabled(false);
bPanel.add(disconnect);
tf.addActionListener(this);
add(tf, BorderLayout.NORTH);
add(ta, BorderLayout.CENTER);
add(list, BorderLayout.EAST);
add(bPanel, BorderLayout.SOUTH);
connect.addActionListener(this);
disconnect.addActionListener(this);
// end ClientPanel constructor
public void actionPerformed(ActionEvent ae)
if (ae.getSource() == tf)
String temp = tf.getText();
pw.println(userName+": "+temp);
tf.setText("");
else if (ae.getSource() == connect)
if(tf.getText() == null || tf.getText().equals(""))
ta.append("Must enter a name to connect\n");
else
userName = tf.getText();
connect.setEnabled(false);
disconnect.setEnabled(true);
tf.setText("");
try
socketToServer = new Socket("127.0.0.1", 3000);
pw = new PrintWriter(new OutputStreamWriter
(socketToServer.getOutputStream()), true);
br = new BufferedReader(new InputStreamReader
(socketToServer.getInputStream()));
catch(UnknownHostException uhe)
System.out.println(uhe.getMessage());
catch(IOException ioe)
System.out.println(ioe.getMessage());
t = new Thread(this);
t.start();
pw.println(userName);
pw.println(userName +" has entered the chat.");
else if (ae.getSource()== disconnect)
try
t.interrupt();
socketToServer.close();
catch(IOException ioe)
System.out.println(ioe.getMessage());
// end actionPerformed
public void run()
for(;;)
try
String temp = br.readLine();
ta.append(temp + "\n");
catch(IOException ioe)
System.out.println(ioe.getMessage());
// end run
// end ClientPanel
服务器:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.awt.*;
public class ThreadedServerWithPresence
public static void main(String[] args)
ArrayList<ThreadedHandlerWithPresence> handlers;
try
handlers = new ArrayList<ThreadedHandlerWithPresence>();
ServerSocket s = new ServerSocket(3000);
for(;;)
Socket incoming = s.accept( );
new ThreadedHandlerWithPresence(incoming,
handlers).start();
catch (Exception e)
System.out.println(e);
class ThreadedHandlerWithPresence extends Thread
Socket incoming;
ArrayList<ThreadedHandlerWithPresence> handlers;
PrintWriter pw;
BufferedReader br;
String userName;
public ThreadedHandlerWithPresence(Socket i,
ArrayList<ThreadedHandlerWithPresence> handlers)
incoming = i;
this.handlers = handlers;
handlers.add(this);
public void setUserName(String userName)
this.userName = userName;
public String getUserName()
return userName;
public void run()
try
br = new BufferedReader(new InputStreamReader
(incoming.getInputStream()));
pw = new PrintWriter(new OutputStreamWriter
(incoming.getOutputStream()),true);
String firstLine = br.readLine();
setUserName(firstLine);
for(;;)
String temp = br.readLine();
System.out.println("Message read: " + temp);
for(int i = 0; i < handlers.size(); i++)
handlers.get(i).pw.println(temp);
catch (Exception e)
System.out.println(e);
finally
handlers.remove(this);
【问题讨论】:
【参考方案1】:客户
您的 run 方法不处理中断,因此 for 循环不会结束,它会继续尝试接收消息。
您必须添加一个可以中断并抛出InterruptedException
的操作,在这种情况下 Thread.sleep 将是一个不错的选择,同时还可以降低 CPU 使用率(您不需要每时每刻都检查新消息)。
try
for (; ; )
try
String temp = br.readLine();
ta.append(temp + "\n");
catch (IOException ioe)
System.out.println(ioe.getMessage());
Thread.sleep(10);
catch (InterruptedException e)
System.out.println("Disconnected.");
服务器
当br.readLine()
返回null
时,表示连接已被客户端关闭,您应该停止接收消息。
String temp = br.readLine();
if(temp == null)
break;
【讨论】:
解决了!非常感谢!以上是关于Java:使用 AWT 按钮断开与聊天服务器的连接的主要内容,如果未能解决你的问题,请参考以下文章