TCP网络编程实现聊天室功能代码详解

用go tcp实现简单的在线群聊功能 go tcp 群聊 阅读详情

测试驱动开发
1,开发服务端
(1),创建一个服务端程序,开启监听端口
(2),开始不断等待客户端的请求,一旦来一个客户端请求,就开启一个线程为其服务
(3),服务端线程-run
------接收客户端注册的用户名,并且回馈“欢迎×××进入聊天室”
------改进代码更简洁
------后续客户端给我发什么,我就给他回什么
------客户端A给我发什么,我就给其他的客户端(B,C)发送“A说:××××”
------新增一个集合来存储我们客户端的信息(记录哪些客户端连接着服务端)
2,开发客户端
(1),创建一个跟服务端的连接
------测试目标:测服务端是否可以处理多个客户端请求
(2),向服务端注册用户信息
------“请输入用户名:”
------方式一:服务端收到客户端连接请求后,将这个信息发给客户端
------方式二:这个信息在客户端实现
(3),成功接收服务端的消息
(4),引入多线程来改进,一个负责读,一个负责写
------ReadThread,WriteThread 划分好工作范围
------把通用对象的创建移到构造方法里面,run就更加可以专注自己的业务
3,私聊 @姓名#内容

 

分析:
1.用tcp编程:客户端和服务器端
2.服务器来了个客户就开启一个线程与客户聊天,将多个客户的线程存在集合中
3.客户端先发用户名,再才能发消息聊天
4.一个客户端向服务器发送消息,服务要将这个消息发给其他所有客户
5.客户要用两个线程,一个读的线程,一个写的线程
6.整个项目功能:群聊和私聊

群聊:客户端->发消息->服务器将客户端的消息转发->给所有其他客户端,线程集合
私聊:客户端->发消息->服务器将客户端的消息转发->指定私聊的用户

package com.qf.day35.zy1;

import java.io.IOException;
import java.net.Socket;

/**
 * @Author LXM
 * @Date 2020/3/27 0027
 */
public class ChatClient {
    public static void main(String[] args) throws IOException {
        //创建客户端socket,第一个参数服务端ip,第二个参数服务端的端口号
        Socket socket1=new Socket("127.0.0.1",9999);

        //创建写入线程对象和读取的线程对象与服务器间进行通信
        WriteThread wt=new WriteThread(socket1);
        ReadThread rt=new ReadThread(socket1);

        //启动线程
        wt.start();
        rt.start();
    }
}
package com.qf.day35.zy1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * @Author LXM
 * @Date 2020/3/27 0027
 */
public class ReadThread extends Thread {
    /**
    *声明一个读取的网络字符输入流
    */
    BufferedReader r;

    /**
    *通过构造方法将用户socket对象伟过来,用socket创建网络读取流,来读取服务器发送消息
    */
    public ReadThread(Socket socket1) {
        try {
            r=new BufferedReader(new InputStreamReader(socket1.getInputStream()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
       try {
          while (true){
              //读取服务器发送的消息
              String receiveMess=r.readLine();
              //将接收消息输出
              System.out.println(receiveMess);
          }
       }catch (Exception e){
           e.printStackTrace();
       }
    }
}
package com.qf.day35.zy1;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * @Author LXM
 * @Date 2020/3/27 0027
 */
public class WriteThread extends Thread {
    /**
    *声明一个网络字符输出流,向服务器发消息
    */
    BufferedWriter w;

    /**
    *通过构造方法将当前用户socket对象传过来,用socket对象创建网络字符输入流,向服务器发消息
    *@param socket1
    */
    public WriteThread(Socket socket1) {
        try {
            w=new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        Scanner input=new Scanner(System.in);

        try {
            //1.第一次要将客户端用户名发送服务器
            System.out.println("请输入用户名:");
            String cname=input.nextLine();
            //将用户名发送给服务器
            w.write(cname);
            //换行
            w.newLine();
            //刷新
            w.flush();

            //2.循环向服务器发消息
            while (true) {
                //从控制台接收要发送的消息
                String sendMess = input.nextLine();
                //将消息写入网络中,通过socket发给服务器
                w.write(sendMess);
                //换行
                w.newLine();
                //刷新
                w.flush();
            }
        } catch (IOException e) {
                e.printStackTrace();
        }
    }
}
package com.qf.day35.zy1;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author LXM
 * @Date 2020/3/27 0027
 */
public class ChatServer {
    /**
    *声明一个集合存所有客户端对应线程对象
    */
    public static List<ServerThread> clientThreads=new ArrayList();

    public static void main(String[] args) throws IOException {
        //创建服务端socket
        ServerSocket ss=new ServerSocket(9999);
        System.out.println("客户端与服务器正在连接中...");
        while (true){
            //监听客户端,并接收客户端socket
            Socket socket1=ss.accept();
            System.out.println("来了一个客户");
            //来了一个客户端,开启一个服务端线程,专门用来与当前客户端聊天
            ServerThread st=new ServerThread(socket1);
            //将当前客户对应线程对象存在集合中
            clientThreads.add(st);
            //启动线程
            st.start();
        }

    }
}
package com.qf.day35.zy1;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;

/**
 * @Author LXM
 * @Date 2020/3/27 0027
 */
public class ServerThread extends Thread {
    /**
    *声明读客户端消息的网络字符输入流
    */
    BufferedReader r;
    /**
     *声明写客户端消息的网络字符输出流
     */
    BufferedWriter w;

    /**
    *通过构造方法将当前服务端线程对应客户端的socket传过来,用socket创建网络读写流与对应客户端聊天
    *@param socket1
    */
    public ServerThread(Socket socket1) {
        try {
            r=new BufferedReader(new InputStreamReader(socket1.getInputStream()));
            w=new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            /*1.欢迎信息*/
            //接收客户端的用户名
            String cname=r.readLine();
            //准备欢迎信息
            String welcomeMess="欢迎"+cname+"进入聊天室";
            //将客户端姓名存在当前客户端对应服务器的线程中,作为服务端线程名称
            Thread.currentThread().setName(cname);

            //遍历所有客户端对应线程集合,将当前用户的欢迎信息转发给所有用户
            for(ServerThread t1:ChatServer.clientThreads){
                //将消息写入当前t1线程对应客户端
                t1.w.write(welcomeMess);
                //换行
                t1.w.newLine();
                //刷新
                t1.w.flush();
            }

            //群聊,循环聊天
            while (true){
                /*1.接收当前客户端发的消息*/
                String recieveMess=r.readLine();
                //判断客户是群聊还是私聊
                if (recieveMess.startsWith("@")){//私聊,@姓名#内容
                    //将私聊的内容进行拆分
                    String[] s=recieveMess.substring(1).split("#");
                    //获得拆分后私聊对象姓名
                    String receiveName=s[0];
                    //获得私聊的内容
                    String receiveWord=s[1];
                    //处理私聊内容
                    String word2=Thread.currentThread().getName()+"悄悄对你说:"+receiveWord;
                    //遍历线程集合,找到私聊的用户,将私聊的内容转发给指定用户
                    for (ServerThread t1:ChatServer.clientThreads){
                        if (t1.getName().equals(receiveName)){
                            //将消息写入当前t1线程对应客户端
                            t1.w.write(word2);
                            //换行
                            t1.w.newLine();
                            //刷新
                            t1.w.flush();
                            break;
                        }
                    }
                }else{//群聊
                    //将当前客户端的消息进行处理
                    String word=Thread.currentThread().getName()+"说:"+recieveMess;

                    /*2.再将当前客户端发的消息转发给其他所有客户端*/
                    //遍历所有客户端对应线程集合来将消息转发给每个客户
                    for (ServerThread t1:ChatServer.clientThreads){
                        if (!t1.getName().equals(Thread.currentThread().getName())){
                            //将消息写入当前t1线程对应客户端
                            t1.w.write(word);
                            //换行
                            t1.w.newLine();
                            //刷新
                            t1.w.flush();
                        }
                    }
                }
            }

        } catch (SocketException e1){//有用户退出了就会抛出这个异常
            //1.获得退出的用户信息
            String exitMess=Thread.currentThread().getName()+"退出了聊天室!";

            /*2.将退出的用户所对应服务器端的线程从线程集合中删除*/
            //遍历当前线程集合,找到当前要退出线程对象,然后再删除
            for (int i=0;i<ChatServer.clientThreads.size();i++){
                if (ChatServer.clientThreads.get(i).getName().equals(Thread.currentThread().getName())){
                   //根据找到要删除的线程对象的索引,将当前线程对象从集合中删除
                    ChatServer.clientThreads.remove(i);
                    break;
                }
            }

            /*3.将当前用户退出的消息转发给所有其他用户*/
            //遍历集合,将线程退出消息发给所有用户
            try {
                for (ServerThread t1 : ChatServer.clientThreads) {
                    //将消息写入当前t1线程对应客户端
                    t1.w.write(exitMess);
                    //换行
                    t1.w.newLine();
                    //刷新
                    t1.w.flush();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

java大作业网络聊天室 这个项目是我大一的java期末大作业,学习了一个学期的成果,编程能力不够,做的并不够好,写在这里记录一下自己的成长,也欢迎大家给出宝贵意见! 该篇博客写一个基于java的单/多人网络即时聊天室,聊天室 ... 阅读详情

相关推荐

c++网络编程实战入门(实现聊天室)

epoll 使用详解 https://www.cnblogs.com/fnlingnzb-learner/p/5835573.html

weixin_36328380的博客 8304

MFC多人在线聊天室

基于MFC的C++的select模型的TCP聊天室 采用select网络模型,支持多人同时登陆,功能有上线、下线、群聊、私聊 使用CjsonObject进行数据传递,使用了心跳包进行判断下线的情况。

不算太晚 5373

Java网络编程--TCP+多线程 实现聊天室群聊功能

Java网络编程–TCP+多线程 实现聊天室群聊功能 功能描述: 简单的聊天室,可以有多个用户同时加入聊天,每个用户可以随时发送消息,其他用户都会收到该用户的信息(显示发送者姓名) 分析: 1.采用TCP实现,服务端需要完成的任务: ​ (1)为每个加入聊天室的用户创建一个服务线程,该线程用于接收该用户的信息并发送给其他用户 ​ (2)用户加入和退出聊天室时给出相应的提示信息 ​ (3)用户退出时...

Eileen___的博客 2042

基于 MFC 的网络聊天室

基于 MFC 的网络聊天室,实现群聊,一对多和一对一聊天。

h_ing_的博客 2316

利用Java网络编程实现简单聊天室

最近学到了Java的网络编程,对TCP协议以及UDP协议有了一些初步的认识,现在尝试使用TCP协议建立一个简单的多人聊天室,去实现多人在线聊天。 以下是具体实现思路(受某位老师启发…): 经过最初的学习,我们知道TCP协议是在两台计算机之间建立连接,然后可以把数据当作双向字节流进行交换, 以便达到传输的目的。但是这样只能达到双人聊天(私聊)的效果,而聊天室的特点在于某一个客户端发出的消息,在聊天...

Wang_YuHeng的博客 1678

Java——多人聊天室(基于TCP的网络编程——Socket)

Java——多人聊天室(基于TCP的网络编程——Socket) 服务端源代码: import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.PrintWri

qingsatianxia的博客 1万+

基于java TCP实现网络通信聊天室《建议收藏附完整源码》

1.1 前言 在信息化社会的今天,网络飞速发展,人们对网络的依赖越来越多,越来越离不开网 络,由此而产生的聊天工具越来越多,类似 MSN、QQ,网络聊天时一类的聊天系统的发展日 新月异,因此产生了制作一个类似 QQ的网络聊天工具的想法,且通过制作该程序还能更好 的学习网络软件编程知识。 网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯。 网编程中有两 个主要的问题, 一个是如何准确的定位网络上一台或多台主机, 另一个就是找到主机后如何 可靠高效的进行数据传输。 在 TCP/IP 协议中..

java李阳勇的博客 6048

使用C语言实现TCP网络通信:服务端和客户端完整源码

使用C语言实现TCP网络通信:服务端和客户端完整源码随着互联网的发展,TCP/IP协议已成为网络通讯的基础。C语言具有高效、可靠的特性,是实现TCP网络通信的常用语言之一。本文将提供完整的服务端和客户端源码,帮助读者了解基本的TCP网络通信实现方式。

CodeLancerX的博客 609

python网络编程与使用TCP协议实现聊天室

网络编程 网络编程从大的方面说就是对信息的发送到接收,中间传输为物理线路的作用。 网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。中间最主要的就是数据包的组装,数据包的过滤,数据包的捕获,数据包的分析,当然最后再做一些处理,代码、开发工具、数据库、服务器架设和网页设计等。 套接字( Socket)是网络通信的关键,套接字也是应用程序和网络协议的接口。套接字由IP和端口号组成。网络层通信主要由TCP和UDP两种通讯。

个人学习笔记库,一篇一篇记录成长的足迹 6272

c++/MFC CSocket仿QQ聊天软件,实现1对1聊天,群聊

本实例,仿照qq,实现了点对对,1对多的聊天功能,具体解释见:http://blog.youkuaiyun.com/open520yin/article/details/8222279 相当适合新手学习,注释非常清楚。包含,服务端和客户端2套代码。 加载就可以运行成功。先运行服务端,再运行客户端。

用C++基于UDP_TCP实现聊天室,文件传输功能

用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文件传输功能 用C++基于UDP_TCP实现聊天室,文

Linux网络编程项目——C语言基于TCP通信协议实现的网络聊天室

目前,网络已经成为人们日常生活中不可缺少的部分,网络聊天也正在一步步的取代短信的使用。本文主要介绍如何利用 网络编程 + 多线程编程 实现一个简易的网络聊天室。

2301_80350206的博客 3349

用友U8其中一个账套提示演示期已到期-修复方法

【事件始末】 一朋友求助,反馈使用的用友U8,很多年了! 突然发现其中账套2021年的一个账套打不开,提示演示期限已到期! 但是其他账套完全正常,可以打开,没有任何问题。 不管是还原老旧备份,还是重装软件问题依旧,无法自己解决。 客户查询报表结算账期,情况比较紧急,于是求助我们。 经过多次反复琢磨和烟酒,终于于晚上23点59分给弄了出来,也总是圆满解决问题了。 【问题分析】 该用户打的是 U82X免狗补丁,估计是该补丁文件设置了 最大有效期,补丁到期了导致的。 也有可能是程序...

u010431289的博客 2万+

Java网络编程小项目——聊天室

学习了网络编程后,我们都可以实现通过TCP协议进行服务端和客户端之间的简单通信但是这远远不过瘾啊!我想要一个那种带界面的,可以实现多人聊天的聊天室。我就是这样的,终于按耐不住诱惑花了两天时间根据TCP通信做了一个这样的聊天室小项目如果也有想我一样的盆友,实现时没了思路,可以参考一下我的哦(˵¯͒〰¯͒˵)

m0_74808313的博客 6234

STM32CubeMx + FatFs 实战:SD卡DMA传输中断回调问题深度解析

本文深度解析了在STM32CubeMx环境下,结合FatFs文件系统并使用DMA进行SD卡读写时,程序可能出现的“卡死”问题。核心原因在于HAL库的弱函数回调机制未被正确处理,导致DMA传输完成中断后,状态机锁死。文章提供了两种实战修复方案:直接修改HAL库文件或在用户代码中重写回调函数,并给出了关键的配置检查点与调试技巧,帮助开发者彻底解决SD卡DMA传输中断回调失效的难题。

weixin_29176179的博客 331

瑞萨 RL78 开发环境实战:从 CS+ for CC 到 e² studio 高效开发

本文详细介绍了瑞萨RL78单片机开发环境的选择与配置,对比分析了CS+ for CC和e² studio的特点及适用场景。内容涵盖环境安装、工程创建、调试技巧、外设驱动开发和低功耗设计等实战经验,为开发者提供全面的RL78入门指南,帮助快速上手并高效开发。

4k5l6j7h8的博客 242

Python TCP并发编程详解及代码实现-以BIO&NIO&AIO模型实现聊天室为例

Python TCP并发编程详解及代码实现-以BIO&NIO&AIO模型实现聊天室为例

研一旺旺的博客 3979

Xilinx IP核 Block Memory Generator v8.4 的使用

本文主要介绍如何使用并初始化 Xilinx 提供的IP核 Block Memory Generator v8.4`,为了确保成功初始化,还对其进行了一个简单的仿真,更多细节请参考官方手册。

高阶近似的博客 1万+

java网络程序设计 聊天室之私聊、群聊和清屏功能的实现

TCP聊天室实现了私聊、群聊和清屏的功能,简陋的UI界面,一个服务器端,支持多个客户端之间的通信。 项目代码:https://pan.baidu.com/s/17iegRam4KnWvcWHw3mvpxg 提取码:e8gx 服务器端: 可以开多个客户端进行客户端之间的通信。 客户端: 系统功能简介: 1.客户端登录成功后可以查看聊天室用户列表,并可以进行个人聊天和群聊。 ...

青红造了个大白之成长记 1万+

第十五章数据管理成熟度评估【6’】(DAMA-CDGA 2022年以后历年模拟题真题汇总,基本包含所有考点。)

第十五章数据管理成熟度评估【6’】(DAMA-CDGA 2022年以后历年模拟题真题汇总,基本包含所有考点。)

JasonH2021的博客 405

【零基础学习CAPL】——弹窗信息提示

不用手动制作Panel窗口,直接使用CAPL脚本实现弹窗提示。//没有wait超时,等待测试人员确认//有wait超时,对话框在超时后自动终止//有wait超时,可以显示一个资源,即对话框可以显示额外的信息。/*参数说明text:显示在弹窗中的内容,长度限制在4096字符timeout:弹窗自动结束的时间,单位:ms。若为0,则无超时控制heading:对话框文本上方的标题。字符串最大长度限制在256个字符。resource:URL或文件路径。字符串的最大长度是有限的(512个字符)。

LOVE135149的博客 268

实现基于Linux网络编程+多线程编程的简易网络聊天室

众所周知,网络聊天室的应用已经融入我们生活的方方面面,微信、QQ、飞书等等,这篇文章介绍如果利用套接字编程(网络编程)+多线程编程实现一个简易的网络聊天室。相信通过对这个网络聊天室的编写,我们可以对网络编程和多线程编程相关知识有更进一步的了解。当然这个网络聊天室还有非常多可以完善的地方,比如加入线程池、完善收发机制等等。

Leon_Chenl的博客 2447

数学建模Matlab算法,第七章 对策论

对策论作为研究竞争与决策的数学理论,从零和对策到非常数和对策,为分析各类博弈问题提供了系统框架。其核心要素包括局中人、策略集和赢得函数,通过稳定解、Nash平衡点等概念揭示竞争规律。该理论广泛应用于经济、军事、政治等领域,不仅提供具体分析工具,更改变了决策思维方式,强调在互动中实现理性选择。对策论既揭示了竞争本质,也凸显合作价值,为解决社会矛盾、促进共赢发展提供了重要启示,在全球化背景下将发挥更大作用。

unber的博客 111

[Qt] 基于Tcp协议的聊天室实现(Chat Room 局域网通信)

时间:2016年12月11日 一、写在前面: 平时做图形学的东西多一些,虽然一直对网络编程很感兴趣,但是没有什么机会去尝试一下。最近正好赶上期末的课程实习,然后就参考Qt官方的 Network Programming References,写了一个局域网群聊软件,还算比较好看吧~ ,因为是自己的提交的作业,所以比较简陋将就一下,主要功能有: (1) 用户...

RyuZhihao123 的博客 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

06 java GUI 网络编程:图形界面聊天室

仿照第4篇笔记的形式,笔者决定将GUI和网络编程部分用综合练习的方式来总结。练习项目是有图形界面的聊天室,用到了GUI中的javax.swing包和网络编程中的TCP/socket编程。GUI部分的难点是图形控件的API较为复杂,设置不同属性需要很多的方法和字段,需要参考API手册和网上的一些图形界面作品的代码,不过GUI代码的结构较为固定(相对于聊天室简单的界面而言),容易总结固定格式。网络编程

Aal Izz Well 2万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

上一篇: 网络编程——TCP网络编程&UDP编程
下一篇: 自定义连接池&实现DataSource的连接池&dbcp连接池(BasicDataSource)&c3p0连接池(ComboPooledDataSource)&druid连接池(DruidDataSo
Java_LXM
博客等级 码龄7年 39粉丝 32原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值