学习Java的每一个人都知道,聊天室是每一个程序员都要过手的项目,根据要求的不同,聊天室的实现可易可难。

我今天的聊天室程序主要实现的功能是:

1、私聊功能

2、群聊功能

3、查看成员列表功能

4、退出聊天室功能

5、发送文件功能

内容比较简单,是学完JavaSE的一次知识总结,没有用到界面等,都是在控制台上进行输出的。希望能给大家提供借鉴。代码如下,程序在最后打包,希望对于初学者的同学

package org.westos.client;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;import org.westos.client.Config.Config;
import org.westos.util.InputAndOutputUtil;
import org.westos.util.InputUtil;/*** 客户端* @author 虎**/
public class Client {private static Socket s;private static InputStream is;private static OutputStream os;private static Scanner sc;private static Config config;private static  String clientName;public static void main(String[] args) {sc = new Scanner(System.in);try {s = new Socket("LocalHost", 9999);os = s.getOutputStream();is = s.getInputStream();//注册------->不停的去注册while(true) {System.out.println("请设置您的昵称");clientName = sc.nextLine();os.write(clientName.getBytes());os.flush();//读取服务器的反馈byte[] result = new byte[1024];int len = is.read(result);String str = new String(result, 0, len);if(str.equals("yes")) {System.out.println("注册成功");break;}else {System.out.println("请重新输入");}}ClientReadThread thread = new  ClientReadThread(is);thread.start();boolean isRun = true;//开始聊天while(isRun) {System.out.println("请选择要进行的操作: 1,私聊  2,公聊  3,在线列表 4 ,退出 聊天 5,发送文件6,下载文件");int chioce =InputUtil.inputIntType(new Scanner(System.in));switch (chioce) {case 1:System.out.println(1);privateChat();break;case 2:  System.out.println(2);publicChat();break;case 3:    System.out.println(3);onlineList();break;case 4:    System.out.println(4);exitChat();isRun = false;break;case 5:   System.out.println(5);sendFile();break;case 6 : System.out.println(6);downloadFile();break;}}}catch (Exception e) {e.printStackTrace();}System.exit(0);}private static void downloadFile() {// TODO Auto-generated method stub}private static void sendFile() throws IOException {//现主要实现私发System.out.println("请输入接收文件的用户姓名:");String receiver  = sc.nextLine();System.out.println("请选择您要发送的文件:(输入具体路径)");String filePath = sc.nextLine();//构建文件File file = new File(filePath);String fileName = file.getName();long fileLength = file.length();String msg = clientName + ":" + receiver +":" + (fileName + "#" + fileLength) + ":" + Config.MSG_SEBDFILE+":";//使用内存操作流输入byte[] msgBytes = msg.getBytes();//空字节数组byte[] emptyBytes = new byte[1024*10-msgBytes.length] ;//利用工具将文件转化为字节数组byte[] fileBytes = InputAndOutputUtil.readFile(filePath);//System.out.println("经过工具后,文件变化为字节的大小为:"+fileBytes.length);ByteArrayOutputStream baos = new ByteArrayOutputStream();baos.write(msgBytes);baos.write(emptyBytes);baos.write(fileBytes);byte[] allBytes = baos.toByteArray();//System.out.println("客户端发出的数据总共字节大小:"+allBytes.length);//通过输出流输出到服务器中os.write(allBytes);os.flush();}private static void exitChat() throws IOException {//退出聊天System.out.println("谢谢使用,再见");String msg = clientName+ ":" + "null" + ":" + "null" +":"+ Config.MSG_EXIT;os.write(msg.getBytes());//关闭 }private static void onlineList() throws IOException {System.out.println("******当前在线的好友有******");String msg = clientName + ":" + "null" + ":" + "null" + ":" +Config.MSG_ONLINELIST; os.write(msg.getBytes());}@SuppressWarnings("static-access")private static void publicChat() throws IOException {System.out.println("----------------欢迎您公聊模式--------------");System.out.println("请输入您要发的消息:");String msg = sc.next();//没有发送者用null来代替//消息格式: 发送者:接受者:所发信息:消息类型msg = clientName + ":"+"null"+":" + msg + ":" + config.MSG_PUBLICCHAT;os.write(msg.getBytes());}@SuppressWarnings("static-access")private static void privateChat() throws IOException {System.out.println("----------------欢迎您进入私聊模式--------------");//消息个数:接受者+发送消息+消息类型System.out.println("请输入接受者的姓名:");String receiver = sc.nextLine();System.out.println("请输入您要给他(她)话:");String msg = sc.next();//消息格式: 发送者:接受者:所发信息:消息类型msg = clientName + ":" + receiver +":"+ msg +":"+ config.MSG_PRIVATECHAT ;os.write(msg.getBytes());}
}
package org.westos.client;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;import org.westos.client.Config.Config;
import org.westos.util.InputAndOutputUtil;/*** 客户端读取输入流的线程* @author 虎**/
public class ClientReadThread extends Thread{private InputStream is;public ClientReadThread(InputStream is) {super();this.is = is;}@Overridepublic void run() {try {while(true) {byte[] bytes = new byte[1024*10];int len = is.read(bytes);String infomation = new String(bytes, 0, len);String[] info = infomation.split(":");String clientName = info[0];String receiver = info[1];String msg = info[2];int infoType =Integer.parseInt(info[3]);//私聊模式//System.out.println(infomation);if(infoType == (Config.MSG_PRIVATECHAT)) {System.out.println(clientName+"@你说:"+msg);}else if(infoType == (Config.MSG_PUBLICCHAT)) {System.out.println(clientName+"对大家说:"+msg);}else if (infoType == Config.MSG_ONLINE) {System.out.println(clientName+msg);}else if(infoType == (Config.MSG_ONLINELIST)) {System.out.println(msg);}else if(infoType == Config.MSG_EXIT) {System.out.println(msg);}else if(infoType == Config.MSG_SEBDFILE) {String[] file = msg.split("#");String fileName = file[0];long fileLength = Long.parseLong(file[1]);System.out.println(clientName+"给您发来一个文件:"+ fileName + "文件大小为:"+fileLength);byte[] memoryBytes = new byte[1024];int memoryLength = 0;//int len1 = infomation.getBytes().length;//不断的去读取ByteArrayOutputStream baos = new ByteArrayOutputStream();int len1 = infomation.getBytes().length;//System.out.println("读取的消息的长度:"+len1);while (true) {int len2= is.read(memoryBytes);baos.write(memoryBytes, 0, len2);//实际长度memoryLength += len2;//判断截止标记//System.out.println(memoryLength);//System.out.println(fileLength);  31879if (fileLength == memoryLength) {break;}//System.out.println("ha2");}//System.out.println("最终的长度:"+memoryLength);byte[] fileBytes = baos.toByteArray();//调用工具boolean flag = InputAndOutputUtil.writeFile("D:/"+fileName, fileBytes);//针对不同情况进行判断//System.out.println("ha3");if (flag) {System.out.println("文件接受成功!保存在D:/"+fileName+"中,请前往查看");break;}else {System.out.println("文件接受失败!");}}}} catch (IOException e) {e.printStackTrace();}}}
package org.westos.server;import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;/*** * @author 代虎**/
public class Server {private static ServerSocket ss;private static Socket s;private static InputStream is;private static OutputStream os;static HashMap<String, Socket> map = new HashMap<String, Socket>() ;public static void main(String[] args) {int num = 1; try {ss = new ServerSocket(9999);System.out.println("服务器已启动...");while (true) {s = ss.accept();is = s.getInputStream();os = s.getOutputStream();System.out.println("第"+ (num++)+"个客户端接入");new SaveClientThread(s, map).start();;}} catch (Exception e) {e.printStackTrace();}}}
package org.westos.server;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;import org.westos.server.config.Config;/*** 存取客户的信息* @author 代虎**/
public class SaveClientThread extends Thread{private Socket s;private InputStream is;private OutputStream os;private String clientName;private Config config;private HashMap<String, Socket> map = new HashMap<String,Socket>();public SaveClientThread(Socket s, HashMap<String, Socket> map) {this.s = s;this.map = map;}@Overridepublic void run() {while(true) {byte[] name = new byte[1024];try {is = s.getInputStream();os = s.getOutputStream();int len = is.read(name);clientName = new String(name, 0, len);if(map.containsKey(clientName)) {os.write("no".getBytes());}else {map.put(clientName, s);os.write("yes".getBytes());System.out.println("当前在线好友:");for(String client:map.keySet()) {System.out.println(client);}break;}} catch (IOException e) {e.printStackTrace();}}//给客户端反馈上线的消息for(String userName:map.keySet()) {//本人上线不需要踢提醒自己if(userName.equals(clientName)) {continue;}else {Socket socket = map.get(userName);String msg = clientName+":"+ userName +":"+ "上线了" +":"+ Config.MSG_ONLINE;try {socket.getOutputStream().write(msg.getBytes());} catch (IOException e) {e.printStackTrace();}}//System.out.println("发送成功");}new ServerTransmitThread(s, map).start();;}
}
package org.westos.server;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;import org.westos.server.config.Config;public class ServerTransmitThread extends Thread{private OutputStream os;private InputStream is;private Socket s;private  HashMap<String, Socket> map = new HashMap<String, Socket>() ;public ServerTransmitThread(Socket s, HashMap<String, Socket> map) {super();this.s = s;this.map = map;}@SuppressWarnings("unused")@Overridepublic void run() {try {is = s.getInputStream();while(true) {//先定义50kbbyte[] bytes = new byte[1024*10];int len= is.read(bytes);String infomation = new String(bytes, 0, len);String[] info = infomation.split(":");String sendName = info[0];String receiver = info[1];String context = info[2];int infoType =Integer.parseInt(info[3]);//公聊if(infoType == (Config.MSG_PRIVATECHAT)) {Socket socket = map.get(receiver);socket.getOutputStream().write(infomation.getBytes());}//私聊else if(infoType == (Config.MSG_PUBLICCHAT)) {for(String str:map.keySet()) {Socket socket = map.get(str);socket.getOutputStream().write(infomation.getBytes());}}//在线列表else if(infoType == Config.MSG_ONLINELIST) {Socket socket = map.get(sendName);int num = 1;StringBuffer sb = new StringBuffer();for(String str:map.keySet()) {sb.append(num++).append("、").append(str).append("\n");}String msg  = sendName +":"+ receiver+":" + (sb.toString())+":" + Config.MSG_ONLINELIST;Socket socket2 = map.get(sendName);socket2.getOutputStream().write(msg.getBytes());}//退出聊天室else if (infoType == Config.MSG_EXIT) {//在map中移除该用户map.remove(sendName);String msg = sendName+"下线了";for(String str:map.keySet()) {msg = "null"+ ":"+ str + ":" + msg + ":" + infoType;Socket socket = map.get(str);socket.getOutputStream().write(msg.getBytes());}}//发送文件else if (infoType == Config.MSG_SEBDFILE) {//System.out.println("发送到服务器端文件总共字节大小"+infomation.getBytes().length);Socket socket = map.get(receiver);String[] file = context.split("#");String fileName = file[0];long fileLength = Long.parseLong(file[1]);String msg = sendName + ":" + receiver +":" + context+ ":" + Config.MSG_SEBDFILE+":";byte[] msgBytes = msg.getBytes();byte[] emptyBytes = new byte[1024*10-msgBytes.length] ;//读取文件byte[] memoryBytes = new byte[1024];int memoryLength = 0;ByteArrayOutputStream baos = new ByteArrayOutputStream();//System.out.println("读取开始了吗?");//不断的去读取while (true) {//System.out.println("1读取开始了");int len2= is.read(memoryBytes);//System.out.println("2到这了吗");baos.write(memoryBytes, 0, len2);//baos.flush();//实际长度memoryLength += len2;//System.out.println("3到这了吗");//判断截止标记//System.out.println("1:"+memoryLength);//System.out.println("2:"+len2);if (fileLength == memoryLength) {break;}//System.out.println("3");}byte[] fileBytes = baos.toByteArray();baos.reset();//重置,继续使用该输出流对象写数据到内存中//System.out.println("4");baos.write(msgBytes);baos.write(emptyBytes);baos.write(fileBytes);//内存中已经有这些数据,需要拼接成一个大的字符数组发过去byte[] allBytes = baos.toByteArray();//System.out.println("发送的长度:"+allBytes.length);socket.getOutputStream().write(allBytes);}}} catch (IOException e) {//  e.printStackTrace();}}}

工具包:

package org.westos.server.config;
/*** 常量(相当于客户端与服务器之间的人协议一样)* @author 代虎**/
public class Config {public static final int MSG_PRIVATECHAT = 100;//私聊public static final int MSG_PUBLICCHAT = 200;//公聊public static final int MSG_ONLINE = 300;//上线public static final int MSG_ONLINELIST = 400;//在线列表public static final int MSG_EXIT = 500; //退出public static final int MSG_SEBDFILE= 600;//发送文件public static final int MSG_DOWNLOAD= 700;//下载文件}
package org.westos.util;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;public class InputAndOutputUtil {public static byte[] readFile(String path) {File file = new File(path);// 数组用来保存读取的数据 相当于水池byte datas[] = null;if (!file.exists()) {datas = null;} else {try {// 字节数组输出流 用来往内存中写字节数组 可以用来拼接字节数组ByteArrayOutputStream baos = new ByteArrayOutputStream();// 创建文件输入流FileInputStream fis = new FileInputStream(file);// 用来保存每次读的数据 相当水瓢(每次读1024字节 但是不一定每次能读这么多 实际读取的长度用len保存)byte data[] = new byte[1024 * 1024];// 用来保存每次读取的字节大小int len = 0;// 不断的读取 直到数据读完while ((len = fis.read(data)) > 0) {// 把每次读入的数据 存放在字节数组流的内存中baos.write(data, 0, len);}// 把字节数组流中的数据转为字节数组datas = baos.toByteArray();baos.flush();baos.close();// 关闭流fis.close();} catch (Exception e) {e.printStackTrace();}}return datas;}public static boolean writeFile(String path, byte datas[]) {try {File file = new File(path);FileOutputStream fos = new FileOutputStream(file);fos.write(datas);// 倾倒关闭fos.flush();fos.close();return true;} catch (Exception e) {e.printStackTrace();return false;}}
}
package org.westos.util;import java.util.Scanner;public class InputUtil {//一直要我们录入整数为止public static int inputIntType(Scanner sc) {int choose = 0;while (true) {try {//录入用户输入的整数choose = sc.nextInt();break;} catch (Exception e) {sc = new Scanner(System.in);System.out.println("输入的类型不正确,请重新输入:");}}return choose;}
}

Java——实现聊天室相关推荐

  1. JAVA版聊天室小软件

    这是一篇关于JAVA的聊天室室小软件,用的swing的技术同时也用到了socket.今天发布出来,希望能帮到大家. 文章目录 开发环境 项目结构 下载地址: 一.运行画面展示 二.代码部分 1.客户端 ...

  2. Java+Swing聊天室

    Java+Swing聊天室 一.系统介绍 二.系统展示 1.发送消息 2.清屏 三.系统实现 四.其他 1.其它系统 2.获取源码 一.系统介绍 本系统实现了简单的聊天室功能:发送消息.清屏.退出系统 ...

  3. java 嘻嘻哈哈聊天室

    服务端 package 夏日聊天室; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.I ...

  4. 2020暑假集训项目——Java简易聊天室

    经过一周的学习与搬砖,我成功的完成了暑假集训的第一个项目--Java简易聊天室,这里对整个项目做一个总结.(文末附下载地址) 本项目支持的功能: 1.可同时开启多个客户端进行多人聊天: 2.可与在线的 ...

  5. 基于java的聊天室系统设计与实现(项目报告+开题报告+答辩PPT+源代码+部署视频)

    项目报告 Java网络聊天室系统的设计与实现 计算机从出现到现在有了飞速的发展,现阶段的计算机已经不单单是用于进行运算的独立的个体了,跟随计算机一同发展的还有互联网技术,经过了长久的发展,互联网技术有 ...

  6. Java网络聊天室---个人博客

    Java网络聊天室 ---个人博客 一.项目简介 功能描述: 使用图形用户界面和socket通信,能实现一个聊天室中多人聊天,可以两人私聊,可以发送文件. 实现类似QQ用户注册.登录.聊天等功能. 参 ...

  7. java webscoket聊天室

    java webscoket聊天室 http://www.whohelpme.com/chats/index.html 欢迎使用 核心代码 package com.summer.whm.web.con ...

  8. 当年的聊天室,今天的我(java实现聊天室群聊功能)

    预备小知识连接: 小小聊天室,慢慢的回忆啊!(TCP 通信实现) 先看效果 主要可以分为三个层:服务端层,客户端层,还有就是工具层: 服务断层:包括接收数据,以及转发数据(数据输出输入流): 客户端层 ...

  9. java仿聊天室项目总结_Java团队课程设计-socket聊天室(个人总结)

    Java团队课程设计-socket聊天室(个人总结) 一.团队课程设计博客链接 二.本人负责模块或任务说明 任务1 服务端对socket线程的接受以及对客户端的数据转发操作 任务2 数据库的查找,添加 ...

  10. java netty聊天室_netty实现消息中心(二)基于netty搭建一个聊天室

    前言 上篇博文(netty实现消息中心(一)思路整理 )大概说了下netty websocket消息中心的设计思路,这篇文章主要说说简化版的netty聊天室代码实现,支持群聊和点对点聊天. 此demo ...

最新文章

  1. oracle11gasm,Oracle11gASM之ACFS创建案例
  2. 持续20年,一场威胁Linux存亡的诉讼终结束
  3. 实验七 不同网段的dhcp
  4. jquery easyUi的学习笔记{一头扎进EasyUI}
  5. 利用python进行数据分析微盘_谁有有《利用Python进行数据分析》pdf 谢谢
  6. cacti支持中文办法
  7. 抽象代数之S3的自同构群和S3的内自同构群
  8. python+ffmpeg视频转码转格式
  9. Mezzanine学习---使用自定义模板
  10. spark 终止 运行_如何在数据源运行ou时停止spark流
  11. ADI Blackfin DSP处理器-BF533的开发详解61:DSP控制ADXL345三轴加速度传感器-LCD(含源码)
  12. HCNA学习笔记(一)
  13. 计算机考研复试——离散数学知识点
  14. dbus系列教程(2)理解dbus核心概念
  15. 小程序开发框架WePY和mpvue使用感受
  16. 视频教程-人物绘画教程--成品-原画设计
  17. 如何在远程的linux服务器中搭建禅道及bugfree
  18. uni app 手机端导航栏自定义
  19. 大学计算机高海波目录,华中师范大学
  20. Python 的 f`` 字符串

热门文章

  1. 深入浅出地理解STM32中的定时器工作原理
  2. 图片转换svg并修改颜色
  3. MPEG音频文件格式(包括MP3文件格式)(1)
  4. pdca计算机术语,PDCA在计算机基础课程中的应用研究
  5. python必背英语单词的手机软件_有哪些适合背英语单词的手机app?
  6. 伺服电机常用参数设置_伺服电机的一般调试步骤
  7. 李嘉诚的商业忠告(转)
  8. 服务器文件系统格式,2. Linux 文件系统
  9. 强生全视旗下可同时矫正视力并缓解过敏性眼痒的隐形眼镜获批
  10. 基于单片机的红外光控灯系统