Socket编程(三)---仿QQ多人聊天实例

仿QQ聊天软件(登录界面、好友界面、聊天界面)-Java(Swing、Socket) 主要运用swing和serversocket、socket写的仿QQ聊天室,深入学习并运用了swing相关组件和socket通信 阅读详情

从上篇文章我们实现了一个简单的socket实例。实例的功能为当一个客户端连接服务端的时候,服务端打印客户端的连接信息,并向客户端发送一组数据并在服务端接收数据和打印,数据内容为服务器当前时间。
这次的实例,目的是为了模仿QQ上和好友聊天的功能,也就是用户登录后,点击用户头像,发送信息,好友就会接受到信息。

1.服务端

public class ChatServer {
    //用于保存客户端连接的Map
    public static Map<Integer, Socket> users = new HashMap<>();

    public static void main(String[] args) {
        ServerSocket server = null;
        System.out.println("服务端应用启动.....");
        try {
            server = new ServerSocket(7456);// 绑定本地的端口号
            Socket connection = null;
            while (true) {
                connection = server.accept();// 接收一个连接,在没有客户端访问的时候,accept会一直阻塞
                DataInputStream reader = new DataInputStream(connection.getInputStream());
                int uid = reader.readInt();//用户在连接的时候会先发送一个表示ID的数据
                // 获取客户端发来的数据
                System.out.println("一个连接建立:" + connection.getInetAddress() + ",用户ID:" + uid);
                // 在服务器用户列表中加入一个连接
                users.put(uid, connection);
                ServerThread thread = new ServerThread(reader);
                thread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (server != null)
                    server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这里的服务端使用了线程来实现数据的读写,和上篇文章的服务端()处理方式相比,上篇文章在和客户端建立一次连接并处理完一次事情后就断开了连接,这样无法实现多次数据的发送。在学习过程中,借鉴过网友的代码,代码类似下面的:

            //此代码与主要代码无关,只是用来分析问题
            ServerSocket server = new ServerSocket(7456);
            while (true) {
                Socket socket = server.accept();
                DataInputStream in = new DataInputStream(socket.getInputStream());
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                while (true) {
                    // 读取来自客户端的信息
                    String accpet = in.readUTF();
                    System.out.println(accpet);
                    // 服务器端发给客户端
                    System.out.println("服务器:" + accpet);
                    out.writeUTF("服务器:" + accpet);
                }
            }

通过上面代码,是可以实现双向通信,而且网上只要搜socket仿qq之类的,出来都是类似模式的。这样的交互模式,是可以让初学者体会到双向交互,但是这个交互是客户端和服务端之间。而且,最大的不足还有:通过上面代码我们可以发现,创建一个连接后进入while()就不会跳出,也就是说,一次只能有一个连接。所以,在我们这边使用线程来实现,在每次创建后使用线程来处理和每个客户端的数据交互。这样就可以实现多人聊天。线程实现代码如下:

public class ServerThread extends Thread {

    private DataInputStream reader;

    public ServerThread(DataInputStream reader) {
        this.reader = reader;
    }

    @Override
    public void run() {
        try {
            while (true) {
                String data = reader.readUTF();//获取客户端数据
                System.out.println(data);
                String[] ss = data.split(",");//数据发送格式
                Integer id = Integer.valueOf(ss[0]);//,前表示用户想法送信息的ID
                String msg = ss[1];//用户发送的数据内容

                Map<Integer, Socket> users = ChatServer.users;
                Socket toP = users.get(id);//根据ID从所有连接用户中获取对应连接
                DataOutputStream writer = new DataOutputStream(toP.getOutputStream());
                writer.writeUTF(msg);//发送数据
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.服务端

服务端为了实现用户在发送数据的同时也可以接收到别的用户发送来的数据,这里实现了读写的分离-也就是用户端在启动后会相应启动两个线程来实现用户对连接中数据的读和写。

//处理读的线程
public class ReadThread extends Thread {

    private Socket socket;

    public ReadThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try (DataInputStream reader = new DataInputStream(socket.getInputStream())) {
            while (true) {
                String data = reader.readUTF();
                System.out.println(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//处理写的线程
public class WriteThread extends Thread {

    private Socket socket;

    public WriteThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        Scanner scanner = new Scanner(System.in);
        try (DataOutputStream writer = new DataOutputStream(socket.getOutputStream())) {
            while (true) {
                String msg = scanner.nextLine();
                writer.writeUTF(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//创建连接的类ChatClient 
public class ChatClient {
    public static void main(String[] args) {
        Socket socket = null;
        try {
            socket = new Socket("localhost", 7456);// 连接地址和端口号
            DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
            int id = (int) (Math.random() * 1000);
            System.out.println("用户" + id + "与服务器成功建立连接......");
            // 向客户端发送本连接ID,ID为随机数产生
            writer.writeInt(id);
            //创建读写线程
            WriteThread wt = new WriteThread(socket);
            ReadThread rt = new ReadThread(socket);
            // 开启读写分离的线程
            wt.start();
            rt.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.测试和总结

服务端应用启动.....

在启动两个客户端后

用户565与服务器成功建立连接......
用户638与服务器成功建立连接......
服务端应用启动.....
一个连接建立:/127.0.0.1,用户ID:565
一个连接建立:/127.0.0.1,用户ID:638

之后,我们在ID565的控制台中向ID638发送数据,由于这里的限制,我使用英文的,来分隔,逗号前表示想访问的ID,逗号后面则是真正的聊天内容。其实,QQ聊天也是一样,在我们点击一个用户头像发送数据时,发送的数据也不单单就我们输入框的值,也会包含对方信息以及你的信息。

用户565与服务器成功建立连接......
638,你好,我是565

在638的控制台中,我们可以看到565发送来的数据

用户638与服务器成功建立连接......
你好,我是565

多人聊天的思路和功能基本实现,如果能用Swing做个窗口,那就更好了!

源码位置:https://github.com/oDevilo/Java-Network

网络编程(三)---- MFC 仿QQ聊天软件 今天来八一八,MFC的SOCKET 编程,利用CSocket实现一个基于TCP实现一个QQ聊天程序。你会发现,MFC要比WIN32 简单的多。但是如果你不理解具体API socket基础知识,你可能会觉得有一点费解。 所以在开始之前 我还是请大家先看看http://blog.cs 阅读详情

相关推荐

Java实现基于TCP协议(Socket编程)的QQ聊天和文件传输

一、文档适用对象 本文档不适用于较为基础的学习,主要面向需要提交类似要求的课程作业的同学,本文主要介绍我的系统操作流程,文章最后附源代码。 基于Java语言,实现了TCP协议下的QQ聊天和文件传输,主要涉及两个原理: 1. Socket编程实现客户端和服务器之间传递消息 Java 网络编程 之 socket 的用法与实现 2. 文件传输 java模拟TCP通信--实现客户端上传文件到服...

DebugMakesMeHappy的博客 6011

Socket编程——功能类似QQ的Java聊天程序(文字聊天、传输文件)

实现功能 验证用户登录 两个用户间的文字聊天 多用户群聊 两个用户之间传输二进制文件 客户端和服务器间通信协议设计

qq_49588762的博客 1885

Python通过Socket实现QQ聊天功能

Python通过Socket实现QQ聊天功能@TOC 服务器端代码tcp_server_chat.py #/usr/bin/python3 import socket import threading socket_list = {} # 用来存放所有客户端的链接,通过用户名查找socket list_socket = {} # 存放所有的用户,通过socket 获取用户名 # 服务器对获取...

huokundian的博客 3911

socket仿qq聊天工具(二)(扩展博客)

最近由于电脑出了点问题,学校那边临近毕业又一直有事耽误了不少的时间,这里就直接把所有的代码粘贴上来。附上运行结果,我要开始下面数据库的学习了。 由于这次的demo涉及到了两个项目,这里就直接把两个项目的项目结构都粘贴上来,这个阶段的项目我都是用Eclipse来完成的,等到javaweb阶段可能我就要换IDEA了。因为就这两个工具来说。现在肯定是IDEA占的市场要大,但是Eclipse也拥有除了IDEA以外最大的市场份额,而且Eclipse与IDEA相比Eclipse是最原生的,作为初学者建议用Eclipse

cdut2016的博客 499

视频教程-网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天-Java

网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天 IT行业...

weixin_32917065的博客 1446

winform中socket实现即时通讯(仿qq聊天)

c# winform socket实现即时通讯(仿qq)

gmandlyh的专栏 9212

网络编程Scoket通信之简单模拟QQ对话!(控制台)

服务器: package com.softeem.scokt; import java.io.IOException; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class ServerDemo {

SS__FF的博客 1008

C++在线多人聊天室

基于SOCKET套接字的聊天程序 当初没有考虑要和别人一起开发什么,所以没有注释, 我还是很相信自己码风的,你肯定看得懂 虽然努力了但还是BUG多多,仅供参考,下次更新就是在暑假了 窝还是一个可怜的高中OIer就不要在意那么多细节嘛 服务端(cmd界面) #include <winsock2.h> #include <windows.h> #include <thr...

saxiy的博客 7508

APl-线程模拟多人聊天

首先像前面所说,我们是不是要建一个服务器端,和一个客户端 ,那么我们现在就把服务器模拟成是一个群聊,这个群聊里面可以进人,我每运行一次窗体就进一个人,而且我发的信息每一个运行的窗体就相当于一个用户,每一个用户他都能接收到这个信息,Ok,我们接下来看代码演示。3:服务器的线程,通过代码我们可以看到,服务器的线程他所做的事情,就是给每个客户端都有发送和接受信息的功能,然后再接收到客户端所发出的信息,将他转换成字符流,然后再通过输出流,对他进行输出,输出给每一位加入群聊的对象。今天我们来讲最基础的模拟多人聊天。

m0_70812512的博客 181

基于Python guI的多人聊天室的设计与实现

现在,即时聊天系统已成为 Internet 上的主要交流工具,并且涌现出大量的AP和平台。这些AP和平台都拥有更加完善的交换机制,使得人们可以更加便捷地进行沟通和交换信息。广域网的聊天系统多重多样,知名的软件主要有 Facebook、腾讯 QQ 等。局域网聊天通信软件也有很多,最著名的应该是飞秋。为了学习和应用 Windows 网络通信编程,我们学习了相关知识,为了应用实践,使用网络通信中的 TCP 和 UDP 编程,实现了多人在线聊天系统。

m0_56073435的博客 5717

Socket通信_java仿qq聊天_java_javasocket_javaqq_socket视频_

基于TCP协议,用Java语言,仿QQ通信,简单实现视频聊天及私聊功能

【JAVA实战】用socket通信编程制作多人聊天室

在七个层级关系中,我们讲的socket属于传输层,其中UDP是⼀种⾯向⽆连接的传输层协议。UDP不关⼼对端是否真正收到了传送过去的数据。如果需要检查对端是否收到分组数据包,或者对端是否连接到⽹络,则需要在应⽤程序中实现。UDP常⽤在分组数据较少或多播、⼴播通信以及视频通信等多媒体领域。在这⾥我们不进⾏详细讨论,这⾥主要讲解的是基于TCP/IP协议下的socket通信。 socket是基于应⽤服务与TC............

陈橘又青的博客 8587

深度强化学习系列(13): 策略梯度(Policy Gradient)

对于DQN来说使用一个网络直接逼近了值函数,最后取得了非常不错的效果, 但是对于一些连续性控制或者动作空间特别大的环境来说,很难全部计算所有的值函数来得到最好的策略,那么直接计算策略的方法就别提出来了。 回顾一下前面几篇,所谓的策略,其实就是状态到动作的映射数学表达为 π:s→aπ:s→a\pi : s \to a, 我们用ττ\tau 表示状态s到最后一个状态的一个序列,表示为: τ:st...

深度强化学习(DeepRL)探索博客 4642

socket多人聊天程序C语言版(一)

socket编程client和server直接通信是很简单的,就是一个发送一个接收就完了,但这却是基础。如果还不是很了解的话请参考这两篇文章。 socket1V1聊天小程序(TCP): http://blog.youkuaiyun.com/qq_18297675/article/details/51052189 socket1V1聊天小程序(UDP): http://blog.youkuaiyun.com/qq_1

_ACME_的博客 3万+

高通AI Engine SDK(QNN)使用教程(环境配置、模型转换、量化、推理、分析)

高通AI Engine使用教程

weixin_51031772的博客 1万+

Linux下离线安装Google Chrome

目录背景一、下载并安装Google Chrome二、下载并安装依赖包1.libvulkan.so.1()(64bit)2.读入数据总结 背景 项目中服务器被要求不能连接外网,不能直接联网安装,所以需要下载Google Chrome安装包和依赖包,然后离线安装。 linux下步骤都一样,不管ubuntu还是centos只是需要下载对应系统的文件包即可。 本机系统:CentOS 7 一、下载并安装Google Chrome 官方下载地址http://www.google.cn/chrome/browser/d

ancientapesman的博客 1万+

java 网络编程五 (仿QQ聊天程序)

学完了socket通讯后,在老师的要求下,写了一个仿qq的聊天程序: 在服务器端 用一个HashMap 维护所有用户相关的信息,从而能够保证和所有的用户进行通讯。 客户端的动作: (1)连接(登录):发送userName    服务器的对应动作:1)界面显示,2)通知其他用户关于你登录的信息, 3)把其他在线用户的userName通知当前用户 4)开启一个线程专门为当前线程服务 (

Dragon_Dai_2017的博客 1万+

【vue看板】

大屏看板提示:以下是本篇文章正文内容,下面案例可供参考提示:这里对文章进行总结:代码量较多,看板中的。

weixin_46223284的博客 2772

socket多人聊天程序C语言版(二)

1V1实现了,1V多也就容易了。不过相对于1V1的程序,我经过大改,采用链表来动态管理。这样效率真的提升不少,至少CPU使用率稳稳的在20以下,不会飙到100了。用C语言写这个还是挺费时间的,因为什么功能函数都要自己写,不像C++有STL库可以用,MFC写就更简单了,接下来我还会更新MFC版本的多人聊天程序。好了,废话少说,进入主题。这个程序要解决的问题如下: 1.CPU使用率飙升问题 –>用链表

_ACME_的博客 2万+

关于旋转矩阵的左乘与右乘问题

最近在阅读框架源码时被旋转矩阵左乘右乘绕的云里雾里,故写下一篇记录一下,以防自己不长记性。

菜鸡正在学习 1万+

CLion for Mac(m1)配置GCC编译器

条件:电脑已经下载过XCode 一. 下载HomeBrew homebrew是一款macos,linux下的包管理工具,我们需要使用他来下载GCC 下载方法: 1.打开终端(terminal) 2.输入 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ps.有可能会遇到的问题 我当初下载挂了VPN,优快云上还有很多解决问题的方法,可以将错误信

supermario19的博客 7847

浅谈java中的ServerSocket和Socket的通信原理实现聊天及多人聊天

聊天,QQ,微信,陌陌很多的即时通讯的软件,不管是桌面端还是移动端,在当今社交的时代都是不可或缺的一部分。这时候说Socket和ServerSocket感觉有点老调重弹感觉,相信很多人早就知道如何使用了,而且利用这个通信原理可能已经开发出很多优秀的通信软件吧,但是我感觉这个对于刚接触java网络编程的人来说,学会Socket通信实现聊天软件,是必须的一步,了解其中的原理更是非常重要的一步,对,很多

Mikyou的专栏 1万+

2025_NIPS_RAGRouter: Learning to Route Queries to Multiple Retrieval-Augmented Language Models

该研究聚焦检索增强生成(RAG)场景下的大语言模型(LLM)路由问题,提出了首个RAG感知的路由框架RAGRouter。核心解决现有路由方法依赖静态参数知识、忽略检索文档动态影响的缺陷,通过融合文档嵌入、RAG能力嵌入与对比学习,捕捉RAG引发的模型知识表征变化,为每个查询-文档对选择最优LLM。实验覆盖5个知识密集型任务、15个开源/闭源LLM,验证了RAGRouter在性能上超越最佳单LLM和非RAG感知路由方法,且通过阈值机制实现低延迟约束下的性能-效率平衡。

UnknownBody_2的博客 273

java实现qq聊天(超详细)

java语言实践课内容:聊天室小程序或QQ 功能要求: 聊天室:使用图形用户界面,能实现一个聊天室中多人聊天,可以两人私聊,可以发送文件。 QQ:实现类似QQ用户注册、登录、聊天等功能。 注意:有一定等级。完全照搬别人的代码,不超过70分。 提示:使用socket通信 准备工作 建立包,类,文件 插入图片要创建一个文件夹,文件夹里保存的就是所需要的图片啦,比如我创建的文件夹为image;...

weixin_52879528的博客 2万+

uniapp - 使用web-view加载本地网页vue页面,用webview导入本地网页,uniAPP中使用web-view加载的本地及远程vue页面+双向通讯功能(兼容微信小程序、安卓苹果APP)

uniapp的App端web-view加载本地html,uniapp微信小程序webview加载本地HTML文件,在uniAPP中使用web-view加载的本地及远程vue页面且进行双向通讯,uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。uniapp WebView组件实现本地网页加载与通讯传值,uniAPP如何内嵌webView引入本地的vue网页示例代码,uniapp在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面跳转

🏆 前端领域优质创作者 5226

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: Socket编程(二)---TCP简单实例
下一篇: Socket编程(四)---使用线程池优化服务端
oDeviloo
博客等级 码龄12年 115粉丝 92原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值