300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Java 网络编程实例—多线程聊天室

Java 网络编程实例—多线程聊天室

时间:2020-02-25 17:12:36

相关推荐

Java 网络编程实例—多线程聊天室

多线程聊天室

利用 Java 的网络套接字和 Swing ,设计一个简单的网络多线程聊天室。

一、服务器套接字

首先是服务器端的套接字,其具体代码如下:

package chating;// !/usr/bin/env jdk1.8// encoding:utf-8//@software:IntelliJ IDEA//@pack:chating//@user:彭友聪//@date:/07/27//@time:上午 9:47//@project:IDEA_JAVA//@file:ChatRoomServer.java//Author:御承扬//email:2923616405@import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .ServerSocket;import .Socket;import java.util.HashSet;public class ChatRoomServer {private ServerSocket serverSocket; // 服务器套接字private HashSet<Socket> allSockets; // 客户端套接字集合// 聊天室构造方法public ChatRoomServer(){try {serverSocket = new ServerSocket( 4569 );} catch (IOException e) {e.printStackTrace();}allSockets = new HashSet<>( ); // 实例化客户端套接字集合}// 启动聊天室的方法private void startService() throws IOException {int i=0;while(true) {i++;Socket s = serverSocket.accept(); // 获得一个客户端连接System.out.printf( "用户%d已经进入聊天室\n",i );allSockets.add(s);new ServerThread(s).start();}}// 服务器线程内部类private class ServerThread extends Thread {Socket socket; // 客户端套接字ServerThread(Socket socket) {this.socket = socket;}public void run() {BufferedReader br = null;try {// 将客户端套接字输入流转为字节流读取br = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );while (true ) {String str = br.readLine(); // 读取到一行之后,则赋值给字符串if(str.contains("%EXIT%")) {// 如果文本内容包含"%EXIT%"allSockets.remove( socket ); // 集合删除此客户端连接// 服务器向所有客户端接口发出退出通知sendMessageToAllClient(str.split( ":" )[1]+"用户已退出聊天室");socket.close();return;}sendMessageToAllClient(str); // 向所有客户端发送此客户端发送来的文本消息}} catch (IOException e) {e.printStackTrace();}}/* ** 发送消息给客户端的方法** @param message*/final void sendMessageToAllClient(String message) throws IOException {for (Socket s : allSockets) {// 循环集合中所有的客户端连接PrintWriter pw = new PrintWriter( s.getOutputStream() ); // 创建输出流pw.println( message ); // 输入写入文本pw.flush();}}public static void main(String[] args) {try {new ChatRoomServer().startService();} catch (IOException e){e.printStackTrace();}}}

二、客户端套接字

有了服务器套接字,就要有与之相配套的客户端套接字,代码如下:

package chating;// !/usr/bin/env jdk1.8// encoding:utf-8//@software:IntelliJ IDEA//@pack:chating//@user:彭友聪//@date:/07/27//@time:上午 10:14//@project:IDEA_JAVA//@file:ChatRoomClient.java//Author:御承扬//email:2923616405@/** 聊天室客户端*/import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .Socket;import .UnknownHostException;public class ChatRoomClient {private Socket socket; // 客户端套接字private BufferedReader bufferedReader; // 字节流读取套接字输入流private PrintWriter pWriter; // 字节流写入套接字输出流/** 聊天室客户端构造方法* @param host*服务器 IP 地址* @param port*服务器与客户端互联的端口*/public ChatRoomClient(String host, int port) throws UnknownHostException, IOException {socket = new Socket( host, port ); // 连接服务器bufferedReader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); // 字节流读取套接字输入流pWriter = new PrintWriter( socket.getOutputStream() ); // 字节流写入套接字输出流}/** 聊天室客户端发送消息的方法* @param str 客户端发送的消息*/public final void sendMessage(String str) {pWriter.println( str );pWriter.flush();}/** 聊天客户端获取消息的方法* @return 读取某个客户端发送的消息*/final String receiveMessage() {try {return bufferedReader.readLine();} catch (IOException e) {e.printStackTrace();}return null;}/** 关闭套接字*/public final void close() {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}

三、用户界面

前面两个部分,是属于后台部分,接下来是属于前台部分的用户界面。用户界面由两个部分组成,一个登陆和连接界面,一个是聊天界面。

登陆连接界面

登陆连接界面的代码如下:

package chating;// !/usr/bin/env jdk1.8// encoding:utf-8//@software:IntelliJ IDEA//@pack:chating//@user:彭友聪//@date:/07/27//@time:下午 4:28//@project:IDEA_JAVA//@file:LinkServerFrame.java//Author:御承扬//email:2923616405@import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;public class LinkServerFrame extends JFrame {private LinkServerFrame() {setLayout( null );setBounds(540,200, 400,250 );setVisible( true );setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );JLabel lbIP = new JLabel( "服务器 IP 地址:" );lbIP.setBounds( 10,10,100,30 );lbIP.setVisible( true );JLabel userName = new JLabel( "用户名:" );userName.setBounds( 40,60,50,30 );userName.setVisible( true );JTextField jfIP = new JTextField( ); // IP 地址输入框jfIP.setBounds( 110,10,250,30 );jfIP.setVisible( true );JTextField jfUser = new JTextField( );jfUser.setBounds( 110,60,250,30 );jfUser.setVisible( true );JButton btn = new JButton( "连接服务器" );btn.setBounds( 120,100,100,20 );btn.setVisible( true );btn.addActionListener( new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (!jfIP.getText().equals( "" ) && !jfUser.getText().equals( "" )) {dispose(); // 销毁当前窗体// 创建客户端窗体并传参ClientFrame clientFrame = new ClientFrame( jfIP.getText().trim(), jfUser.getText().trim() );} else {JOptionPane.showMessageDialog( null,"文本框里的内容不能为空!","警告",JOptionPane.WARNING_MESSAGE );}}} );Container center = getContentPane();center.add(lbIP);center.add( jfIP );center.add( userName );center.add( jfUser );center.add( btn );center.setBackground( Color.WHITE );}public static void main(String[] args) {new LinkServerFrame();}}

运行效果如下图:

聊天界面

聊天界面的代码如下:

package chating;// !/usr/bin/env jdk1.8// encoding:utf-8//@software:IntelliJ IDEA//@pack:chating//@user:彭友聪//@date:/07/27//@time:下午 3:31//@project:IDEA_JAVA//@file:ClientFrame.java//Author:御承扬//email:2923616405@import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.IOException;import .UnknownHostException;import java.text.SimpleDateFormat;import java.util.Date;public class ClientFrame extends JFrame {private JTextField tfMessage; // 信息发送文本框private JTextArea textArea; // 信息接收文本域private ChatRoomClient client; // 客户端连接对象// 构造方法public ClientFrame(String ip, String userName) {super("多线程聊天室");setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );setLayout( null );setBounds( 100,50,800,680 );Container c = getContentPane();// 用户名称this.addWindowListener( new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent atg0) {int op = JOptionPane.showConfirmDialog( ClientFrame.this,"确定要退出聊天室吗?", "确定", JOptionPane.YES_NO_OPTION); // 弹出提示框if (op == JOptionPane.YES_OPTION) {client.sendMessage( "%EXIT%:"+userName ); // 发送信息try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}client.close();System.exit( 0 );}}} );// 发送按钮JButton btnSend = new JButton( "发送" );btnSend.setBounds( 680,550,100,30 );btnSend.setVisible( true );btnSend.addActionListener( new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Date date = new Date();SimpleDateFormat df = new SimpleDateFormat( "yyyy年MM月dd日 HH:mm:ss" ); // 设定日期格式client.sendMessage( userName+" "+df.format( date )+": \n"+tfMessage.getText() ); // 向服务器发送消息tfMessage.setText(""); // 输入框为空}} );// 实例化客户端对象try {client = new ChatRoomClient( ip,4569 ); // 创建客户端对象} catch(UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}ReadMessageThread messageThread = new ReadMessageThread(); // 创建读取客户端消息的线程类对象messageThread.start();// 控件初始化JLabel text = new JLabel( "消息对话框:" );text.setBounds( 10,0,200,30 );text.setVisible( true );// 消息对话框textArea = new JTextArea( );textArea.setBounds( 10,30,750,420 );textArea.setVisible( true );textArea.setBackground( Color.LIGHT_GRAY);textArea.setFont(new Font("标楷体", Font.BOLD, 16)); //设置当前字体。// 显示用户名JLabel lblUserName = new JLabel( userName );lblUserName.setBounds( 10,550,50,30 );lblUserName.setVisible( true );tfMessage = new JTextField( );tfMessage.setBounds( 50,550,600,30 );tfMessage.setVisible( true );// 下方面板c.add(text);c.add(textArea);c.add(lblUserName);c.add(tfMessage);c.add(btnSend);c.setBackground( Color.WHITE );setVisible( true );}private class ReadMessageThread extends Thread{private ReadMessageThread() {}public void run() {while (true) {String str = client.receiveMessage(); // 客户端收到服务器发来的文本内容textArea.append( str+"\n" ); // 向文本框添加内容}}}public static void main(String[] args) {new ClientFrame( "192.168.0.105", "吴雅男" );}}

先运行服务器套接字,在运行连接界面两次,效果如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。