局域网聊天软件
需要的前置了解:
- 了解java窗体
- 了解Socket通信
- 了解线程使用
- 了解TCP协议
只要你能了解以上内容,通过自身的应用,即可实现一个简单的局域网聊天软件。
聊天软件实现难点
本项目中
- 客户端向服务端发送的数据分3种:
- 聊天信息
- 新加入的用户姓名(未完善)
- 退出的用户姓名
- 服务端向客户端发送的数据分4种:
- 聊天信息
- 有用户加入
- 服务器断开
- 由用户退出
在本项目中会对发送的数据进行处理,在每个数据前加上一个标识,以便判断是何种情况的数据。
服务器
一开始选择服务器作为第一个实现的目标,实现步骤如下:
- 设计服务器窗口;
- 添加对应窗口监听器(关闭服务器时断开客户端连接);
- 补充监听器按钮逻辑(创建服务器及发送信息);
- 创建额外的线程,循环获取客户端信息。
大体思路就是这个,详细实现(为了方便理解,按照调用方法的顺序来展现代码):
public class ChatServerFrame extends JFrame implements ActionListener{
//此处设计其实不太好,没有实现封装,日后需注意
static String mString;
static JTextArea ChatWindow;
JTextArea InputMessage;
static JTextArea UserName;
//存储用户名称
ArrayList<String> Userlist = new ArrayList<String>();
//存储所有的客户端连接,以便之后进行使用
ArrayList<Socket> socketList = new ArrayList<Socket>();
JTextField getPort;
String Ip;
String stringPort;
int port;
ServerSocket serverSocket = null;
static boolean judge;
public static void main(String[] args) {
ChatServerFrame chatFrame = new ChatServerFrame();
chatFrame.setVisible(true);
}
//窗口实现(不是很重要)
public ChatServerFrame() {
setTitle("服务器聊天窗口");
setSize(700, 550);
setLocationRelativeTo(null);
setLayout(new FlowLayout());
try {
Ip = Inet4Address.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JPanel jPanel = new JPanel(new BorderLayout());
//消息顯示區(莫名其妙就成繁體字了....)
JPanel jp1 = new JPanel(new BorderLayout());
ChatWindow = new JTextArea(17, 45);
ChatWindow.setEditable(false);
ChatWindow.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(ChatWindow);
jp1.setBorder(new TitledBorder("消息显示"));
jp1.add(scrollPane,"Center");
//发出信息框
JPanel jp2Top = new JPanel(new BorderLayout());
JPanel jp2_1 = new JPanel(new BorderLayout());
JPanel jp2_2 = new JPanel(new BorderLayout());
JToolBar toolBar = new JToolBar();
JLabel linkServer = new JLabel("服务器Ip");
JTextField getServer = new JTextField(12);
JLabel linkPort = new JLabel("端口");
getPort = new JTextField(12);
JButton createServer = new JButton("创建服务器");
getServer.setText(Ip);
getServer.setEditable(false);
InputMessage = new JTextArea(5,45);
InputMessage.setLineWrap(true);
createServer.addActionListener(this);
JScrollPane scrollPane2 = new JScrollPane(InputMessage);
toolBar.add(linkServer);
toolBar.add(getServer);
toolBar.add(linkPort);
toolBar.add(getPort);
toolBar.add(createServer);
jp2_1.setBorder(new TitledBorder("信息输入"));
jp2_2.add(toolBar,"North");
jp2_1.add(scrollPane2,"Center");
jp2Top.add(jp2_2,"North");
jp2Top.add(jp2_1,"Center");
//按钮区
JPanel jp3 = new JPanel();
JButton send = new JButton("发送");
send.addActionListener(this);
jp3.add(send);
//用户区
JPanel jp4 = new JPanel(new BorderLayout());
jp4.setBorder(new TitledBorder("用户区"));
UserName = new JTextArea(29,8);
UserName.setEditable(false);
JScrollPane scrollPane3 = new JScrollPane(UserName);
jp4.add(scrollPane3);
jPanel.add(jp1,"North");
jPanel.add(jp2Top,"Center");
jPanel.add(jp3,"South");
this.add(jp4);
this.add(jPanel);
//添加窗口监听器,主要设置关闭窗口时,断开各个客户端的连接
WindowAction windowAction = new WindowAction();
this.addWindowListener(windowAction);
//将服务器姓名传上
String name = "服务器";
Userlist.add(name);
UserName.append(name + "\n");
}
//此处是想着为之后的登陆留接口,并无用处
public ChatServerFrame(String mString) {
this.mString = mString;
}
...
...
//添加窗口监听器
class WindowAction extends WindowAdapter {
//在窗口关闭时,断开和所有客户端的连接
@Override
public void windowClosing(WindowEvent e) {
//如果已经创建服务端并服务端未关闭
if (serverSocket != null && (!serverSocket.