源码下载:http://download.csdn.net/detail/u011983531/9266041

一、服务端

服务端目录结构如下:

这里定义了三个模型:

  • User:对用户的封装,这里只添加了一个name属性
  • Cient:对客户端的封装,客户端包括一个User对象和一个Socket对象
  • Message:对聊天双方传送的消息的封装,包括发送人、接收人、消息内容、消息类型(有上线、下线、聊天三种类型的消息)

ChatServer.java

package com.ghs.chat.server;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Set;import com.ghs.chat.bean.Client;
import com.ghs.chat.bean.Message;
import com.ghs.chat.bean.User;public class ChatServer {private static final int PORT = 5000;private static ServerSocket serverSocket;private static Set<Client> onlines;//在线客户端private static Set<User> users;//在线用户static{try {//创建Socket服务器serverSocket = new ServerSocket(PORT);onlines = new HashSet<Client>();users = new HashSet<User>();} catch (IOException e) {e.printStackTrace();}}public void start(){//服务器始终监听5000端口,当有客户顿请求建立连接时,就开启一个线程,处理该请求try {while(true){Socket socket = serverSocket.accept();new HandlerClientRequestThread(socket).start();}} catch (IOException e) {e.printStackTrace();}}class HandlerClientRequestThread extends Thread{private Socket socket = null;//请求建立连接的客户端private Message message = null;//客户端发来的消息public HandlerClientRequestThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {while(true){ObjectInputStream ois= new ObjectInputStream(socket.getInputStream());message = (Message) ois.readObject();int type = message.getType();User user = null;Message msg = null;switch (type) {case Message.ON_LINE://当有客户端上线时,向所有客户端发送消息user = message.getFromUser(); onlines.add(new Client(user,socket));users.add(user);
//                      System.out.println(user.hashCode()+"..."+users.size());msg = new Message();msg.setContent(users);msg.setType(Message.ON_LINE);sendMessageToAll(msg);break;case Message.OUT_LINE:user = message.getFromUser(); onlines.remove((new Client(user,socket)));users.remove(user);msg = new Message();msg.setContent(users);msg.setType(Message.OUT_LINE);sendMessageToAll(msg);break;case Message.CHATTING://客户端正在聊天sendMessage(message);break;default:break;}}} catch (Exception e) {e.printStackTrace();}}/*** 将发送端的消息转发给接收端* @param message*/private void sendMessage(Message message){//根据发送端指定的接收端的用户,获取接收端的SocketUser toUser = message.getToUser();System.out.println(toUser.getName()+"..."+message.getContent());Socket toSocket=null;for (Client client:onlines) {if(toUser.getName().equals(client.getUser().getName())){toSocket = client.getSocket();}}System.out.println(toSocket==null);//如果接收端在线,就将消息转发给接收端if(toSocket!=null){try {ObjectOutputStream oos = new ObjectOutputStream(toSocket.getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}}//给所有在线客户端发送消息private void sendMessageToAll(Message message){for(Client client:onlines){try {ObjectOutputStream oos = new ObjectOutputStream(client.getSocket().getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}}public void sendMessage(Message message,Socket socket){try {ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {new ChatServer().start();}
}

服务端通过Socket socket = serverSocket.accept(); 不停的监听5000端口,每当有客户端请求建立连接时,就创建一个处理客户端请求的线程,每一个线程代表一个与客户端建立的连接。然后在线程内部通过ObjectInputStream ois= new ObjectInputStream(socket.getInputStream()); 不停的接收客户端发送的消息,收到消息后,再把消息转发给另一个客户端。

二、客户端

客户端目录结构如下:

客户端主要分为两大块,一个是登录模块,另一个是聊天模块。

1、登录模块

首先在mysql数据库中创建一个数据库chat,然后创建一张表tbl_user,如下:

DBUtils.java就是用来与数据库创建连接的,UserService.java就是用来处理登录逻辑的。
登录界面(LoginFrame.java):

2、聊天模块
聊天界面:

ChatClient.java

package com.ghs.chat.client;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;import com.ghs.chat.bean.Client;
import com.ghs.chat.bean.Message;
import com.ghs.chat.bean.User;
import com.ghs.chat.listener.ReceivedMsgListener;public class ChatClient {private static final String HOST = "127.0.0.1";private static final int PORT = 5000;private static Socket socket;private ReceivedMsgListener listener = null;static{try {socket = new Socket(HOST,PORT);} catch (Exception e) {e.printStackTrace();}}/*** 接收消息*/public void receiveMsg(){new Thread(new Runnable() {@Overridepublic void run() {//客户端不停的接收消息while(true){try {ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());Message message = (Message) ois.readObject();listener.onReceived(message);} catch (Exception e) {e.printStackTrace();}}}}).start();}/*** 发送消息* @param content* @param from  发送人* @param to    接收人*/public void sendMsg(String content,String from,String to){System.out.println(content+"..."+from+"..."+to);Message message = new Message();message.setContent(content);message.setFromUser(new User(from));message.setToUser(new User(to));message.setType(Message.CHATTING);try {ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message);oos.flush();System.out.println("finish");} catch (IOException e) {e.printStackTrace();}}public void sendMsg(Message message){ObjectOutputStream oos;try {oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}/*** 客户端上线后,向服务端发送消息* @param from*/public void online(String from){Message message = new Message();message.setFromUser(new User(from));message.setType(Message.ON_LINE);try {ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}/*** 客户端下线后,向服务端发送消息* @param from*/public void outline(String from){Message message = new Message();message.setFromUser(new User(from));message.setType(Message.OUT_LINE);try {ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());oos.writeObject(message);oos.flush();} catch (IOException e) {e.printStackTrace();}}public void setReceivedMsgListener(ReceivedMsgListener listener){this.listener = listener;}
}

当用户登录成功后,会实例化一个Client对象,即与服务端建立连接,然后调用online()方法通知服务端上线了,当用户退出后,会调用outLine()方法通知服务端下线了。另外,客户端定义了一个线程,通过ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 不停的接收服务端发送的消息。当收到消息后,就会调用ReceivedMsgListener中的onReceived方法,因为ChatFrame实现了这个接口,所以具体怎么显示交给ChatFrame就可以了。

Socket一对一聊天实例相关推荐

  1. TCP socket 一对一编程实例中出现“烫烫烫”的问题

    我在tcp socket一对一聊天实例的编程过程中出现了前几个数据能正常运行,但是超过一定空间后就会出现好多"烫烫烫",这个问题困扰了三天,在这三天我对我的程序改了又改,还是没改对 ...

  2. C# Socket实现聊天通信

    C# Socket实现聊天通信 下面这个实例是一个完整的使用Socket实现的聊天(只限于局域网,如果能提供一个高权限的IP就可以实现类似QQ聊天),其中的原理是:首先开启服务端,打开侦听(任何端口为 ...

  3. 【Java线程】简单实现带界面的一对一聊天

    实现原理: 1.构建好窗体,在窗体中创建好相应的布局和控件: 2.为相应的控件(按钮:监听.连接.发送)添加事件: 3.使用到两个线程: a.监听线程:获取服务器端输入的端口号,构建socket,监听 ...

  4. 一对一聊天ajax实现

    前端页面: 好友列表: 好友列表代码: <%@ page language="java" contentType="text/html; charset=UTF-8 ...

  5. java socket 工具_java Socket简易聊天工具

    本文实例为大家分享了一款Socket简易聊天工具,希望大家喜欢. 代码运行如图,看起来还不错 服务端 package qiu; import java.awt.BorderLayout; import ...

  6. uniapp集成腾讯即时通信IM,实现一对一聊天,支持文字、表情、语音、图片、视频

    uniapp集成腾讯即时通信IM,实现一对一聊天,支持文字.表情.语音.图片.视频 原则 拿来即用,节省开发时间 介绍 腾讯的给的例子内容比较乱,我花了好长时间才集成出来,然后对聊天页面做了UI美化. ...

  7. WebSocket(3)---实现一对一聊天功能

    实现一对一聊天功能 功能介绍:实现A和B单独聊天功能,即A发消息给B只能B接收,同样B向A发消息只能A接收. 本篇博客是在上一遍基础上搭建,上一篇博客地址:[WebSocket]---实现游戏公告功能 ...

  8. Java websocket + redis 实现多人单聊天室,多人多聊天室, 一对一聊天

    多人,单聊天室版 FEATURE 多人聊天, 界面简洁美观, 使用ueditor支持发送文字,图片信息 群聊成员列表, 登入登出公告 存储聊天记录, 查看历史消息 技术点 使用CopyOnWriteM ...

  9. Java网络编程,一对一聊天

    Java网络编程,一对一聊天 **这个小任务是来自于B站,他的视频名字就是"Java实现实时聊天互动程序"** 要求:就是有2个类,其中一个客户端和一个服务端.要实现从客户端发消息 ...

最新文章

  1. 201C Fragile Bridges
  2. 参加ISCC2019线下赛感悟
  3. 【转】HMAC哈希消息认证码及算法原理
  4. 使用SQL Server存储ASP.NET Session变量
  5. 95-20-010-协议-Kafka的Request和Response
  6. cocos creator基础-(三十一)超大数值计算
  7. 斐讯K2路由器,版本号V22.6.507.43(最新)刷华硕固件简明教程(附所有工具包)
  8. linux 挂载ISO镜像文件
  9. linux c 读取.bin文件
  10. 隐形交通指挥员:浅述城市轨交信号系统
  11. Kotlin入门:var和val的区别
  12. DUTOJ-1151: 投硬币
  13. 关于maven的创建简单的servlet
  14. 2022CCPC桂林站感想与反思
  15. 莫欺少年穷,看看这10个顶级大公司最初的模样
  16. ZLG震撼发布开源GUI引擎AWTK
  17. H5跳转App、跳转小程序
  18. 运维体系 ------ 技术运营
  19. 去除Neg窗口(警告窗口)
  20. 通过PS给人物制作一种打散效果

热门文章

  1. 内网工具viper的介绍与配置简介
  2. vs2017取消起始页(设定起始页)/(.ashx文件的添加)
  3. 《虚无的十字架》---作者东野圭吾 读后感
  4. Detecting Visual Relationships with Deep Relational Networks(阅读笔记)
  5. 破解系统登录密码与软件密码
  6. 验证tomcat安装成功
  7. 正交矩阵的定义及证明和性质
  8. php 导出mysql 数据库表结构图_导入和导出数据表的图文介绍(phpMyAdmin的使用教程5)...
  9. C++设计模式——组合模式(高屋建瓴)
  10. 海纳百川 有容乃大――采用JSI封装、集成第三方类库