首先,实现的效果如下图:

 这是一个非常经典的例题,几乎在每本程序语言入门书中都会涉及到一部分原理的讲解。我在这里简单地介绍一下代码的实现,让刚学习网络编程的读者更好的理解和实现,二来加深自己的记忆。

  这个原理无非就是 利用服务器端处理消息再返回给客户端,实现客户端之间的信息交互。 这个原理与生活息息相关,比如两部手机之间的电话交流并不是两部机器直接交流,而是通过信息发射台或者卫星来实现信息交互。虽然原理非常简单,但如果想很完整地实现这个功能并不十分容易(至少对我来讲)。

整个程序代码很简短,主要用到的 java Socket套接字、多线程知识。主要难度在于非常容易产生Exception。

下面附上服务器端代码

package chat;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;public class ChatServer {public  static ServerSocket serverForClient=null;public static boolean bool1=false;//用来判断是否连接成功List<Client> clients=new  LinkedList<Client>();public static void main(String[] args) {ChatServer start=new ChatServer();start.runing();}public  void runing()  {//连接客户端,并启动线程Socket serverSocket=null;//这个名字起得非常不好 和关键字SeverSocket重名了,很容易混淆,建议读者改掉,我这里懒得改了try {serverForClient=new ServerSocket(3333);bool1=true;//当服务器连接成功时 为true} catch (IOException e1) {System.out.println("端口被占用,请关闭相关占用程序重启服务器!");}try {   int count=0;while(bool1) {if(count==0) {System.out.println("*********正在等待客户端连接******");}count++;serverSocket =serverForClient.accept();System.out.println("**第"+count+"个客户端正在连接中……");Client cc=new Client(serverSocket);cc.setClient(cc);new Thread(cc).start();clients.add(cc);//new Thread(new Client(serverSocket)).start();}} catch (IOException e1) {e1.printStackTrace();}finally {try {serverSocket.close();} catch (IOException e) { e.printStackTrace();}}}class Client implements Runnable{// 启用线程类来 接受客户端Client me=null;DataInputStream serverIn=null;DataOutputStream serverOut=null;Socket ss=null;public  String accept=null;//这里的字符串名字与accept()方法重名,容易混淆,建议改掉!public Client(Socket s ){ss=s;try {serverIn=new DataInputStream(ss.getInputStream());serverOut=new DataOutputStream(ss.getOutputStream());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void send(String sss)    {try {serverOut.writeUTF(sss);  } catch (IOException e) {e.printStackTrace();}}
public void setClient (Client s) {me=s;}
public void run() {try {    while(bool1) {//服务器端等待接受客户端的消息accept=serverIn.readUTF();for(int i=0;i<clients.size();i++) {//把接受到的消息发送给每一个客户端Client c=clients.get(i);if(me!=c) {c.send(accept+"\n");}}//System.out.println(""+accept); //这句话在代码全部完成前可以用来测试服务器是否收到客户端消息}}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {try {if(ss!=null) ss.close();if(serverIn!=null) serverIn.close();if(serverOut!=null) serverOut.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}

服务器端:建立一个接受 客服端连接的 ServerSocket,当有客户端连接时,得到对应的Socket,并传入给线程,线程保存每一个接入的客服端并接受客服端消息,然后发送给其他所有的客户端。(这相当于一个QQ群,当客户端接入相同的服务器IP和端口时,客户端之间即可实现群聊)

下面附上客户端代码

package chat;import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;import javax.swing.*;public class ChatClient extends JFrame implements ActionListener{public static boolean bool1=false;//用来判断是否连接成功JTextField text=new JTextField();JTextArea area=new JTextArea();    JScrollPane scroll=new JScrollPane(area);Socket clientSocket=null;DataOutputStream clientOut=null;DataInputStream clientIn=null;public static void main(String[] args) {new ChatClient().launchJFrame();}   public void launchJFrame() {this.setBounds(400, 400, 400, 400);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.add(scroll,BorderLayout.CENTER);this.add(text,BorderLayout.SOUTH);text.addActionListener(this);connect();}public void connect() {try {clientSocket=new Socket("localhost",3333);bool1=true;clientIn=new DataInputStream(clientSocket.getInputStream());clientOut=new DataOutputStream(clientSocket.getOutputStream());System.out.println("连接服务器成功");new Thread(new Receiver()).start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void actionPerformed(ActionEvent arg0) {String s=text.getText().trim();// area.setText(s);    try {clientOut.writeUTF(""+s);area.append("我发送的消息:"+s+"\n");clientOut.flush();text.setText("");
//clientOut.close();//这里不能关闭否则没法继续向服务器端发送信息} catch (IOException e) {e.printStackTrace();}}class Receiver implements Runnable{//内部的类中添加线程:接受服务器消息public void run() {while(bool1) {try {String clientAccept=clientIn.readUTF();area.append("接收到的消息:"+clientAccept);} catch (IOException e) {try {if(clientIn!=null)  clientIn.close();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}}}}

客户端:客户端是一个JFrame 窗口,给文本框添加一个ActionListener监视器,将文本框内容输入到输出流中。和服务器端一样创建内部的线程,让线程去获取服务器发送到输出流中的信息并显示在文本区内。

那么客户端和服务器端写好这个程序就基本完成了,先让服务器端运行起来,之后就可以运行多个客户端。客户端将信息发送到服务器,服务器接受并把它发送到其他客户端,即可实现客户端的在线聊天。

到这里来说 功能已经实现了。但是可以预见,即使我试图使用多个catch尽可能地去抓程序中的异常,并使用finally尽量去关闭已经打开且无用的流。我的代码依然有一些问题。

当我关闭一个客户端的时候,服务器端会抛出SocketException异常,虽然这并不影响程序的继续运行。这个问题检查代码用点时间应该也容易解决,不过我已经失去耐心,不想再去花时间处理这种异常问题,读者如果使用我的代码可以在此基础上修改。

java 实现 仿QQ聊天系统 简易地实现 网络 在线聊天 代码详解(附源代码)相关推荐

  1. 复习Java第二个项目仿QQ聊天系统 01(界面部分) Java面试题Redis的过期策略和内存淘汰策略生活【记录一个咸鱼大学生三个月的奋进生活】023

    记录一个咸鱼大学生三个月的奋进生活023 复习Java(仿QQ聊天系统01界面部分) 设置背景(ImgPanel)类 登录界面(LoginFrame)类 注册界面(RegisterFrame)类 好友 ...

  2. 仿QQ聊天系统(JAVA+MySQL)

    摘  要 仿QQ聊天系统是基于MySQL数据库开发工具进行设计,理论研究与实践相结合,利用计算机技术.数据库技术,java技术等对腾讯QQ聊天系统的开发设计进行研究 以JAVA技术为核心,利用计算机局 ...

  3. 复习Java第二个项目仿QQ聊天系统 03(两种通信类、登录以及注册功能完善) Java面试题并发编程相关知识生活【记录一个咸鱼大学生三个月的奋进生活】025

    记录一个咸鱼大学生三个月的奋进生活025 复习Java(仿QQ聊天系统03两种通信类.登录以及注册功能完善) TcpSocket类(与服务器进行通信) Server类(服务器类) TcpMessage ...

  4. java仿qq登录 界面设计,Java Swing仿QQ登录界面效果

    本文实例为大家分享了Java Swing仿QQ登录界面展示的具体代码,供大家参考,具体内容如下 闲来无事将早些时候已实现的QQ登录界面再实现了一遍,纯手工打造(意思是没有用NetBeans.MyEcl ...

  5. Java 开发的QQ聊天系统 窗体程序 功能非常齐全 完整源码

    今天为大家分享一个java语言编的QQ聊天系统,目前系统已经完成了初步功能,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步 开发环境 开发 ...

  6. java实现仿qq界面及功能、网路编程、实现抽象工厂模式、线程池代码与测试

    java实现仿qq界面及功能 用Swing 代码在百度网盘:http://pan.baidu.com/s/1pJjxI4b 具体见https://www.iteye.com/topic/1137293 ...

  7. Java swing 仿QQ实现账号密码输入框

    Java swing 仿QQ之实现账号密码输入框 主要思路是自己定义 AccountPanel 和 PasswordPanel 类,继承JPanel,通过 paintComponent(Graphic ...

  8. java 仿qq mysql_基于Java远程通信(仿QQ)及应用研究设计(MySQL)(含录像)

    基于JAVA远程通信(仿QQ)及应用研究设计(MySQL)(含录像)(毕业论文13000字,程序代码,MySQL数据库) 随着信息社会脚步的日益加快,远程通信的应用正在人们的生产生活中扮演着极其重要的 ...

  9. linux课程设计QQ聊天带界面,仿QQ聊天系统课程设计解析.doc

    仿QQ聊天系统课程设计解析 目录 绪论1 一.需求分析1 1.1软件功能需求分析2 1.2 安全需求分析2 二.总体设计3 2.1 软件结构图3 2.2 功能描述3 2.2.1注册功能概要4 2.2. ...

最新文章

  1. python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表(Ajax 请求数据接口)...
  2. 【组队学习】【24期】河北邀请赛(二手车价格预测)
  3. RTL Schematic 与 Technology Schematic的区别?
  4. 【数据库】Redis是什么
  5. 推荐系统--用户行为和实验设计
  6. Android毛玻璃处理代码(Blur)
  7. Tips--Multisim中压电传感器与电荷源的替代方案
  8. Redis入门篇(安装与启动)
  9. ocs 2007 r2 服务体验
  10. 关于windows的进程处理(三)
  11. mybatis 存储过程 tmp_count_mysql存储过程(一)-navicat与mybatis
  12. 使用WebDeployment Project改善VS2005发布网站
  13. 那些年,我们玩过的酷Q机器人
  14. python selenium模拟鼠标点击_selenium模拟鼠标操作
  15. native数据类型 react_React-Native 之 数据持久化
  16. numpy 矩阵运算
  17. centOS服务器 netstat命令 查看TCP连接数信息(转)
  18. 69张图回顾2021和看透2022
  19. 在阿里云ACP认证考试中授权码有效期时限是多久?
  20. 远程 PC 访问软件

热门文章

  1. Tensorflow入门到实战五(卷积神经网络)
  2. Activity中的数据传送—案例: 购买装备
  3. flashcache安装使用
  4. 管理之道(十) - 你还在崇拜交付速度吗?
  5. Lua热更原理以及加载规则
  6. amd r7 2700u linux,满血双通道R7 2700U?AMD锐龙APU测试
  7. 【GD32】GD32读取ADC数据
  8. 处理器cpu测试工具
  9. Django使用图片验证码加邮箱或手机号登录
  10. 根据时间生成分配批次号