java+socket实现简易局域网聊天室
本文实例为大家分享了java+Socket实现简易局域网聊天室的具体代码,供大家参考,具体内容如下
服务器端
ServerFrame.java
package com.eze.chatroom.server;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.jscrollPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ServerFrame extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField txtPort;
private JLabel lblOnlineCount;
private JTextArea txtAreainfo;
private Server server;
private JTextArea txtAreaPals;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ServerFrame frame = new ServerFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ServerFrame() {
this.setTitle("server");
this.setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 658, 428);
contentPane = new JPanel();
contentPane.setForeground(Color.DARK_GRAY);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblPort = new JLabel("port :");
lblPort.setFont(new Font("宋体", Font.PLAIN, 18));
lblPort.setBounds(14, 13, 72, 31);
contentPane.add(lblPort);
txtPort = new JTextField();
txtPort.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
int c = e.geTKEyChar();
if(!(c > KeyEvent.VK_0 && c < KeyEvent.VK_9)){
e.consume();
}
}
});
txtPort.setFont(new Font("宋体", Font.PLAIN, 20));
txtPort.setBounds(89, 18, 138, 24);
contentPane.add(txtPort);
txtPort.setColumns(10);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(245, 103, 378, 272);
contentPane.add(scrollPane);
txtAreaInfo = new JTextArea();
scrollPane.setViewportView(txtAreaInfo);
txtAreaInfo.setFont(new Font("Monospaced", Font.PLAIN, 20));
JButton btnChange = new JButton("start");
btnChange.addMouseListener(new MouseAdapter() {
private boolean flag = true;
@Override
public void mouseClicked(MouseEvent e) {
String portStr = txtPort.getText().trim();
boolean isvalid = false;
int port = 9999;
if(!(portStr.startsWith("0") || portStr.equals(""))){
port = Integer.valueOf(portStr);
if(port >= 1024 && port <= 65535)
isvalid = true;
}
if(!isvalid){
JOptionPane.showMessageDialog(ServerFrame.this, "invalid port that is expected to put into the range of 1024~65535");
return;
}
if(flag){
btnChange.setText("stop");
txtAreaInfo.append("server started\n");
flag = false;
ServerFrame.this.server = new Server(ServerFrame.this, ServerFrame.this.getTitle(), port);
Thread thdServer = new Thread(new Runnable() {
@Override
public void run() {
ServerFrame.this.server.start();
}
});
thdServer.start();
}else{
btnChange.setText("start");
ServerFrame.this.server.stop();
txtAreaInfo.append("server stopped\n");
flag = true;
}
}
});
btnChange.setFont(new Font("宋体", Font.PLAIN, 19));
btnChange.setBackground(new Color(240, 255, 240));
btnChange.setForeground(new Color(178, 34, 34));
btnChange.setBounds(270, 17, 113, 27);
contentPane.add(btnChange);
JLabel lblPalsOnline = new JLabel("pals online:");
lblPalsOnline.setBounds(18, 73, 113, 18);
contentPane.add(lblPalsOnline);
JLabel lblLogInfo = new JLabel("log info");
lblLogInfo.setBounds(285, 73, 72, 18);
contentPane.add(lblLogInfo);
lblOnlineCount = new JLabel("0");
lblOnlineCount.setBounds(123, 75, 72, 18);
contentPane.add(lblOnlineCount);
JScrollPane scrollPane_1 = new JScrollPane();
scrollPane_1.setBounds(14, 111, 213, 264);
contentPane.add(scrollPane_1);
txtAreaPals = new JTextArea();
scrollPane_1.setViewportView(txtAreaPals);
}
public JLabel getLblOnlineCount() {
return lblOnlineCount;
}
public JTextArea getTxtAreaPals() {
return txtAreaPals;
}
public JTextArea getTxtAreaInfo() {
return txtAreaInfo;
}
}
Server.java
package com.eze.chatroom.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JTextArea;
public class Server {
private ServerSocket server;
private List<Socket> clients;
private Map<String, String> pals;
@SuppressWarnings("unused")
private String name;
private int port;
private ServerFrame frame;
public Server(ServerFrame frame, String name, int port){
this.frame = frame;
this.name = name;
this.port = port;
this.clients = new ArrayList<>();
this.pals = new HashMap<>();
}
public void start(){
try {
this.server = new ServerSocket(port);
System.out.println("server start at port "+port);
while(true){
Socket client = server.accept();
Thread thdHandConn = new Thread(new HandleConnection(client, clients, pals, frame));
thdHandConn.start();
}
}catch(SocketException e){
System.out.println("server stop");
}catch (IOException e) {
e.printStackTrace();
}
}
public void stop(){
try {
for(Socket sock : clients){
sock.close();
}
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void autoRoll(JTextArea area){
area.setCaretPosition(area.getText().length());
}
}
HandleConnnection.java
package com.eze.chatroom.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.text.SimpleDateFORMat;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class HandleConnection implements Runnable {
private Socket client;
private List<Socket> clients;
private Map<String, String> pals;
private ServerFrame frame;
public HandleConnection(Socket client, List<Socket> clients, Map<String, String> pals, ServerFrame frame){
this.client = client;
this.clients = clients;
this.pals = pals;
this.frame = frame;
}
@Override
public void run() {
String username = null;
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
DataInputStream dataInput = new DataInputStream(client.getInputStream());
DataOutputStream dataOutput = new DataOutputStream(client.getOutputStream());
String totalFirst = dataInput.readUTF();
username = totalFirst.split("_")[0];
if(username.equals("")){
dataOutput.writeUTF("no");
client.close();
return;
}
dataOutput.writeUTF("ok");
String hello = formatDate.format(new Date())+"\n"+client.getRemoteSocketAddress().toString()+username+" join romm\n";
frame.getTxtAreaInfo().append(hello);
Server.autoRoll(frame.getTxtAreaInfo());
this.forwardMsg(hello);
clients.add(client);
pals.put(client.getRemoteSocketAddress().toString(), username);
this.updatePalsList();
while(true){
String Word = dataInput.readUTF();
String date = formatDate.format(new Date());
String msg = date+" "+username+"\n"+word;
frame.getTxtAreaInfo().append(msg+"\n");
Server.autoRoll(frame.getTxtAreaInfo());
this.forwardMsg(msg);
}
}catch (SocketException e) {
clients.remove(client);
pals.remove(client.getRemoteSocketAddress().toString(), username);
this.updatePalsList();
String leaveMsg = formatDate.format(new Date())+"\n"+username+" leaved room\n";
this.frame.getTxtAreaInfo().append(leaveMsg);
Server.autoRoll(frame.getTxtAreaInfo());
this.forwardMsg(leaveMsg);
}catch (IOException e) {
e.printStackTrace();
}
}
protected void updatePalsList(){
this.frame.getLblOnlineCount().setText(String.valueOf(clients.size()));
this.frame.getTxtAreaPals().setText("");
for(Map.Entry<String, String> entry : pals.entrySet()){
this.frame.getTxtAreaPals().append(entry.getKey()+" "+entry.getValue()+"\n");
}
}
protected void forwardMsg(String msg){
try {
for(Socket sock : clients){
if(sock != client){
DataOutputStream dataOutput = new DataOutputStream(sock.getOutputStream());
dataOutput.writeUTF(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
ClientLoginViewer.java
package com.eze.chatroom.client;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class ClientLoginViewer extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private ClientWin win;
private JTextField txtUsername;
private JTextField txtServer;
private JLabel lblPort;
private JTextField txtPort;
private Client client;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ClientLoginViewer frame = new ClientLoginViewer();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ClientLoginViewer() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 603, 366);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblNewLabel = new JLabel("username:");
lblNewLabel.setFont(new Font("宋体", Font.PLAIN, 20));
lblNewLabel.setBounds(71, 41, 113, 18);
contentPane.add(lblNewLabel);
txtUsername = new JTextField();
txtUsername.setText("admin");
txtUsername.setBounds(209, 38, 235, 24);
contentPane.add(txtUsername);
txtUsername.setColumns(10);
JLabel lblServer = new JLabel("server:");
lblServer.setFont(new Font("宋体", Font.PLAIN, 20));
lblServer.setBounds(71, 93, 90, 18);
contentPane.add(lblServer);
txtServer = new JTextField();
txtServer.setText("localhost");
txtServer.setColumns(10);
txtServer.setBounds(209, 92, 235, 24);
contentPane.add(txtServer);
lblPort = new JLabel("port:");
lblPort.setFont(new Font("宋体", Font.PLAIN, 20));
lblPort.setBounds(71, 149, 90, 18);
contentPane.add(lblPort);
txtPort = new JTextField();
txtPort.setText("2222");
txtPort.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
int c = e.getKeyChar();
if(c < KeyEvent.VK_0 || c > KeyEvent.VK_9){
e.consume();
}
}
});
txtPort.setBounds(209, 148, 235, 24);
contentPane.add(txtPort);
txtPort.setColumns(10);
JButton btnLogin = new JButton("login");
btnLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnLogin.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String username = txtUsername.getText();
String server = txtServer.getText();
String portStr = txtPort.getText();
if(!this.argsValid(username, server, portStr)){
String error = "please input valid arguments which username, password, server, port"
+ " are not allowed be empty and port should be in the range of 1024~65535";
JOptionPane.showMessageDialog(ClientLoginViewer.this, error);
return;
}
client = new Client(username, server, Integer.valueOf(portStr), ClientLoginViewer.this.win);
if(ClientLoginViewer.this.client.login()){
ClientLoginViewer.this.setVisible(false);
ClientLoginViewer.this.win.setVisible(true);
win.setClient(client);
}else{
JOptionPane.showMessageDialog(ClientLoginViewer.this, "login falied");
}
}
protected boolean argsValid(String username, String server, String portStr){
if(username.equals("") || server.equals("") || portStr.equals(""))
return false;
int port = Integer.valueOf(portStr);
if(port < 1024 || port > 65535)
return false;
return true;
}
});
btnLogin.setFont(new Font("宋体", Font.PLAIN, 20));
btnLogin.setBounds(213, 222, 113, 27);
contentPane.add(btnLogin);
this.initOther();
}
protected void initOther(){
this.win = new ClientWin();
this.setResizable(false);
}
}
ClientWin.java
package com.eze.chatroom.client;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import com.eze.chatroom.server.Server;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.Font;
import javax.swing.JTextArea;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ClientWin extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField txtSendMsg;
private JTextArea txtAreaShowMsg;
@SuppressWarnings("unused")
private Client client;
private DataOutputStream dataOutput;
private JScrollPane scrollPane;
public ClientWin() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 631, 467);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
scrollPane = new JScrollPane();
scrollPane.setBounds(7, 7, 595, 351);
contentPane.add(scrollPane);
txtAreaShowMsg = new JTextArea();
txtAreaShowMsg.setFont(new Font("Monospaced", Font.PLAIN, 20));
scrollPane.setViewportView(txtAreaShowMsg);
txtSendMsg = new JTextField();
txtSendMsg.setBounds(14, 371, 265, 41);
txtSendMsg.setFont(new Font("宋体", Font.PLAIN, 20));
contentPane.add(txtSendMsg);
txtSendMsg.setColumns(10);
JButton btnPost = new JButton("post");
btnPost.addMouseListener(new MouseAdapter() {
private SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void mouseClicked(MouseEvent e) {
String sendMsg = txtSendMsg.getText();
if(!sendMsg.equals("")){
try {
String date = dateFormate.format(new Date());
dataOutput.writeUTF(sendMsg);
ClientWin.this.getTxtAreaShowMsg().append(date+" you\n"+sendMsg+"\n");
Server.autoRoll(ClientWin.this.getTxtAreaShowMsg());
ClientWin.this.txtSendMsg.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
btnPost.setBounds(377, 378, 113, 27);
btnPost.setFont(new Font("宋体", Font.PLAIN, 20));
contentPane.add(btnPost);
this.initOther();
}
protected void initOther(){
this.setResizable(false);
}
public void setClient(Client client) {
this.client = client;
try {
this.dataOutput = new DataOutputStream(client.getClient().getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public JTextArea getTxtAreaShowMsg() {
return txtAreaShowMsg;
}
public void setTxtSendMsg(JTextField txtSendMsg) {
this.txtSendMsg = txtSendMsg;
}
}
Client.java
package com.eze.chatroom.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
public class Client {
private Socket client;
private String username;
private String server;
private int port;
private ClientWin win;
public Client(String username, String server, int port, ClientWin win){
this.username = username;
this.server = server;
this.port = port;
this.win = win;
}
public boolean login(){
try {
client = new Socket(server, port);
DataInputStream dataInput = new DataInputStream(client.getInputStream());
DataOutputStream dataOutput = new DataOutputStream(client.getOutputStream());
dataOutput.writeUTF(username+"_");
String ret = dataInput.readUTF();
if(ret.contains("ok")){
Thread thdReader = new Thread(new ClientReader(client, win));
thdReader.start();
return true;
}
} catch (UnknownHostException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(win, "unknown host");
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public Socket getClient() {
return client;
}
}
ClientReader.java
package com.eze.chatroom.client;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import javax.swing.JOptionPane;
import com.eze.chatroom.server.Server;
public class ClientReader implements Runnable {
private ClientWin win;
private Socket client;
public ClientReader(Socket client ,ClientWin win){
this.client = client;
this.win = win;
}
@Override
public void run() {
this.doHand();
}
protected void doHand(){
try {
DataInputStream dataInput = new DataInputStream(client.getInputStream());
while(true){
String msg = dataInput.readUTF();
win.getTxtAreaShowMsg().append(msg+"\n");
Server.autoRoll(win.getTxtAreaShowMsg());
}
} catch (IOException e) {
//e.printStackTrace();
try {
client.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("client disconnected");
JOptionPane.showMessageDialog(win, "you have been disconnected");
}
}
}
运行效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
相关文章