zl程序教程

您现在的位置是:首页 >  后端

当前栏目

java Socket实现简单在线聊天(三)

JAVA 实现 简单 在线 socket 聊天
2023-09-14 09:04:42 时间
在上一篇,利用线程使服务端实现了能够接收多客户端请求的功能,这里便需要客户端接收多客户端消息的同时还能把消息转发到每个连接的客户端,并且客户端要能在内容显示区域显示出来,从而实现简单的在线群聊。 在实现客户端转发,无非就是增加输出流;而之前客户端都只发不收,这里也需要更改客户端达到循环接收服务端消息的目的,因此也需要实现多线程。 在实现这个功能的时候,偶然想起随机生成验证码的功

在上一篇,利用线程使服务端实现了能够接收多客户端请求的功能,这里便需要客户端接收多客户端消息的同时还能把消息转发到每个连接的客户端,并且客户端要能在内容显示区域显示出来,从而实现简单的在线群聊。


在实现客户端转发,无非就是增加输出流;而之前客户端都只发不收,这里也需要更改客户端达到循环接收服务端消息的目的,因此也需要实现多线程。 在实现这个功能的时候,偶然想起随机生成验证码的功能,于是也灵机一动随机给每个客户端生成一个名字,从而在输出的时候看起来更加像是群聊,不仅有消息输出,还能看到是谁。 实现这些功能之后,基本上就可以几个人同时在线群聊了,因为代码中有main方法,因此可以把服务端和客户端都打成可执行jar包,可参考我的另一篇博文:使用eclipse创建java程序可执行jar包 之后在桌面双击相应的jar文件启动服务端和客户端即可,不需要再依赖eclipse运行。 修改后的客户端代码如下:
* 在线聊天客户端 步骤: 1、生成图形窗口界面轮廓 2、为轮廓添加关闭事件 3、在轮廓中加入输入区域和内容展示区域 4、为输入区域添加回车事件 * 5、建立服务端连接并发送数据 * @author tuzongxun123 public class ChatClient extends Frame { private static final long serialVersionUID = 1L; // 用户输入区域 private TextField tfTxt = new TextField(); // 内容展示区域 private TextArea tarea = new TextArea(); private Socket socket = null; // 数据输出流 private DataOutputStream dataOutputStream = null; // 数据输入流 private DataInputStream dataInputStream = null; private boolean isConnect = false; Thread tReceive = new Thread(new ReceiveThread()); String name = ""; public static void main(String[] args) { ChatClient chatClient = new ChatClient(); chatClient.createName(); chatClient.launcFrame(); * 建立一个简单的图形化窗口 * @author:tuzongxun * @Title: launcFrame * @param * @return void * @date May 18, 2016 9:57:00 AM * @throws public void launcFrame() { setLocation(300, 200); this.setSize(200, 400); add(tfTxt, BorderLayout.SOUTH); add(tarea, BorderLayout.NORTH); // 根据窗口里面的布局及组件的preferedSize来确定frame的最佳大小 pack(); // 监听图形界面窗口的关闭事件 this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); disConnect(); tfTxt.addActionListener(new TFLister()); // 设置窗口可见 setVisible(true); connect(); // 启动接受消息的线程 tReceive.start(); * 连接服务器 * @author:tuzongxun * @Title: connect * @param * @return void * @date May 18, 2016 9:56:49 AM * @throws public void connect() { try { // 新建服务端连接 socket = new Socket("127.0.0.1", 8888); // 获取客户端输出流 dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataInputStream = new DataInputStream(socket.getInputStream()); System.out.println("连上服务端"); isConnect = true; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); // 生成随机的客户端名字 public void createName() { String[] str1 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; Random ran = new Random(); for (int i = 0; i i++) { // long num = Math.round(Math.random() * (str1.length - 0) + 0); // int n = (int) num; int n = ran.nextInt(str1.length); if (n str1.length) { String str = str1[n]; name = name + str; System.out.println(name); } else { i--; continue; this.setTitle(name); * 关闭客户端资源 * @author:tuzongxun * @Title: disConnect * @param * @return void * @date May 18, 2016 9:57:46 AM * @throws public void disConnect() { try { isConnect = false; // 停止线程 tReceive.join(); } catch (InterruptedException e) { e.printStackTrace(); } finally { try { if (dataOutputStream != null) { dataOutputStream.close(); if (socket != null) { socket.close(); socket = null; } catch (IOException e) { e.printStackTrace(); * 向服务端发送消息 * @author:tuzongxun * @Title: sendMessage * @param @param text * @return void * @date May 18, 2016 9:57:56 AM * @throws private void sendMessage(String text) { try { dataOutputStream.writeUTF(name + ":" + text); dataOutputStream.flush(); } catch (IOException e1) { e1.printStackTrace(); * 图形窗口输入区域监听回车事件 * @author tuzongxun123 private class TFLister implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String text = tfTxt.getText().trim(); // 清空输入区域信息 tfTxt.setText(""); // 回车后发送数据到服务器 sendMessage(text); private class ReceiveThread implements Runnable { @Override public void run() { try { while (isConnect) { String message = dataInputStream.readUTF(); System.out.println(message); String txt = tarea.getText(); if (txt != null !"".equals(txt.trim())) { message = tarea.getText() + "\n" + message; tarea.setText(message); } catch (IOException e) { e.printStackTrace(); }

修改后的服务端代码如下:
* java使用socket和awt组件以及多线程简单实现在线聊天功能服务端 : * 实现服务端把接收到的客户端信息转发到所有连接的客户端,并且让客户端读取到这些信息并显示在内容显示区域中。 * @author tuzongxun123 public class ChatServer { public static void main(String[] args) { new ChatServer().start(); // 是否成功启动服务端 private boolean isStart = false; // 服务端socket private ServerSocket ss = null; // 客户端socket private Socket socket = null; // 保存客户端集合 List Client clients = new ArrayList Client public void start() { try { // 启动服务器 ss = new ServerSocket(8888); } catch (BindException e) { System.out.println("端口已在使用中"); // 关闭程序 System.exit(0); } catch (Exception e) { e.printStackTrace(); try { isStart = true; while (isStart) { // 启动监听 socket = ss.accept(); System.out.println("one client connect"); // 启动客户端线程 Client client = new Client(socket); new Thread(client).start(); clients.add(client); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭服务 try { ss.close(); } catch (IOException e) { e.printStackTrace(); * 客户端线程 * @author tuzongxun123 private class Client implements Runnable { // 客户端socket private Socket socket = null; // 客户端输入流 private DataInputStream dataInputStream = null; // 客户端输出流 private DataOutputStream dataOutputStream = null; private boolean isConnect = false; public Client(Socket socket) { this.socket = socket; try { isConnect = true; // 获取客户端输入流 dataInputStream = new DataInputStream(socket.getInputStream()); // 获取客户端输出流 dataOutputStream = new DataOutputStream( socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); * 向客户端群发(转发)数据 * @author:tuzongxun * @Title: sendMessageToClients * @param @param message * @return void * @date May 18, 2016 11:28:10 AM * @throws public void sendMessageToClients(String message) { try { dataOutputStream.writeUTF(message); } catch (SocketException e) { } catch (IOException e) { e.printStackTrace(); @Override public void run() { isConnect = true; Client c = null; try { while (isConnect) { // 读取客户端传递的数据 String message = dataInputStream.readUTF(); System.out.println("客户端说:" + message); for (int i = 0; i clients.size(); i++) { c = clients.get(i); c.sendMessageToClients(message); } catch (EOFException e) { System.out.println("client closed!"); } catch (SocketException e) { if (c != null) { clients.remove(c); System.out.println("Client is Closed!!!!"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭相关资源 try { if (dataInputStream != null) { dataInputStream.close(); if (socket != null) { socket.close(); socket = null; } catch (IOException e) { e.printStackTrace();


【Java】网络编程--Socket与TCP网络通信编程 文章目录 1 Socket 2 TCP网络通信编程 2.1 TCP字节流编程 2.1.1 案例:客户端发送数据,服务端接收并显示 2.1.2 案例进阶:双向通信 2.2 TCP字符流编程 2.3 网络上传文件
java网络编程(2)socket通信案例(TCP和UDP) java生下来一开始就是为了计算机之间的通信,因此这篇文章也将开始介绍一下java使用socket进行计算机之间的通信,在上一篇文章中已经对网络通信方面的基础知识进行了总结,这篇文章将通过代码案例来解释说明。
使用Java Socket手撸一个http服务器 作为一个java后端,提供http服务可以说是基本技能之一了,但是你真的了解http协议么?你知道知道如何手撸一个http服务器么?tomcat的底层是怎么支持http服务的呢?大名鼎鼎的Servlet又是什么东西呢,该怎么使用呢? 在初学java时,socket编程是逃不掉的一章;虽然在实际业务项目中,使用这个的可能性基本为0,本篇博文将主要介绍如何使用socket来实现一个简单的http服务器功能,提供常见的get/post请求支持,并再此过程中了解下http协议
涂宗勋 认真生活,快乐工作,保持理想!https://blog.csdn.net/tuzongxun