一.说明:

​本例是一个简易的Java TCP多人聊天室,先启动服务器端,再启动客户端,客户端敲入用户名,然后可以开始聊天,敲入信息,每一个在线的用户都会收到相应信息。

演示如下图:

二.服务器端代码

ServerMain.java

import java.io.*;

public class ServerMain {

public static void main(String[] args) {

ChatServer server = new ChatServer();

try {

server.ServerStart();

}

catch (IOException e) {

e.printStackTrace();

}

}

}

ChatServer.java

import java.io.*;

import java.net.*;

import java.util.HashMap;

public class ChatServer {

// 设定端口号

private final int port = 12345;

public static HashMap clientMap = new HashMap<>();

public static int onlineNum = 0;

public static void ServerSendToAll(ClientThread thread,String msg) throws IOException {

for (ClientThread t : clientMap.keySet()) {

if (t.clientName.equals(thread.clientName)) {

Message.printMessage(msg);

continue;

}

t.objOutput.writeObject(new DataPacket(Message.CMD.SENDALL, msg));

}

}

public static void ServerSendToAll(ClientThread thread) throws IOException {

onlineNum++;

// 服务端记录

Message.printMessage(thread.clientName + "上线了,当前在线人数" + onlineNum + "人");

// 群发

for (ClientThread t : clientMap.keySet()) {

if (t.login == true) {

t.objOutput.writeObject(new DataPacket(Message.CMD.LOGIN, "当前在线人数" + onlineNum + "人"));

}

}

}

public void ServerStart() throws IOException {

ServerSocket serverSocket = new ServerSocket(port);

Message.printMessage("Server Start.");

// 死循环等待客户端连接

while (true) {

// 每来一个客户端连接,保存Socket对象

Socket clientSocket = serverSocket.accept();

ClientThread client = new ClientThread(clientSocket);

// 每连接一个客户端,创建一个对应的线程类

Thread clientThread = new Thread(client);

// 添加对象-Socket映射

clientMap.put(client, clientSocket);

// 启动线程

clientThread.start();

}

}

}

ClientThread.java

import java.io.*;

import java.net.*;

/*

线程类:处理每一个登录成功的客户端

*/

public class ClientThread implements Runnable {

// 保存每个客户端Socket

private Socket client = null;

public ObjectInputStream objInput = null;

public ObjectOutputStream objOutput = null;

public String clientName = null;

public boolean login = false;

public ClientThread(Socket client) {

this.client = client;

try {

this.objInput = new ObjectInputStream(this.client.getInputStream());

this.objOutput = new ObjectOutputStream(this.client.getOutputStream());

} catch (IOException e) {

Message.printLog(Message.logType.ERROR, "ClientThread:IOException!", true);

e.printStackTrace();

}

}

public int HandleReceiveMsg(Object data) throws IOException {

DataPacket dataPacket = (DataPacket) data;

switch (dataPacket.cmd) {

case LOGIN:

clientName = dataPacket.msg;

login = true;

ChatServer.ServerSendToAll(this);

break;

case SEND:

// 收到消息,调用群发其他用户

String msg = this.clientName + "说:" + dataPacket.msg;

ChatServer.ServerSendToAll(this, msg);

break;

case SENDALL:

// 收到其他用户群发的消息

SendMessage(dataPacket);

break;

}

return 0;

}

public void SendMessage(DataPacket data) throws IOException {

this.objOutput.writeObject(data);

}

public Object ReceiveMessage() throws ClassNotFoundException, IOException {

try {

Object obj = this.objInput.readObject();

return obj;

} catch (EOFException e) {

}

return null;

}

@Override

public void run() {

try {

Object data;

while ((data = ReceiveMessage()) != null) {

HandleReceiveMsg(data);

}

} catch (SocketException e) {

login = false;

} catch (IOException e) {

Message.printLog(Message.logType.ERROR, "ClientThread-run:IOException!", true);

e.printStackTrace();

} catch (ClassNotFoundException e) {

Message.printLog(Message.logType.ERROR, "ClientThread-run:ClassNotFoundException!", true);

e.printStackTrace();

} finally {

// 用户断开连接

if (login == false) {

// 从HashMap 移走映射

ChatServer.clientMap.remove(this);

// 释放资源

if (client != null) {

try {

client.close();

} catch (IOException e) {

e.printStackTrace();

}

}

ChatServer.onlineNum--;

// 打印信息

String msg = this.clientName + "下线了,当前在线" + ChatServer.onlineNum + "人";

Message.printMessage(msg);

try {

ChatServer.ServerSendToAll(this, msg);

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

三.客户端代码

ClientMain.java

public class ClientMain {

public static void main(String[] args) {

ChatClient client = new ChatClient();

client.ClientStart();

}

}

ChatClient.java

import java.io.*;

import java.net.*;

import java.util.Scanner;

public class ChatClient {

private static final int port = 12345;

private static String serverAddress = "localhost";

private Socket client = null;

private ObjectOutputStream objOutput = null;

private ObjectInputStream objInput = null;

public void SendMessage(DataPacket data) throws IOException {

// 发送数据给服务器

objOutput.writeObject(data);

}

public void ClientStart() {

Scanner in = new Scanner(System.in);

String userInput = null;

// 用户输入用户名登录

Message.printLog(Message.logType.INFO, "请输入你的用户名:", false);

userInput = in.nextLine();

// 连接服务器

try {

this.client = new Socket(serverAddress, port);

// 服务器已连接

if (this.client.isConnected()) {

// 获取输出流

this.objOutput = new ObjectOutputStream(this.client.getOutputStream());

// 获取输入流

this.objInput = new ObjectInputStream(this.client.getInputStream());

SendMessage(new DataPacket(Message.CMD.LOGIN, userInput));

// 创建一个线程用于接收信息

ClientReceiveMessageThread receiveMessage = new ClientReceiveMessageThread(this.objInput, userInput);

Thread receiveThread = new Thread(receiveMessage);

receiveThread.start();

// 这个线程用于发送信息

while (true) {

userInput = in.nextLine();

if (userInput != null) {

SendMessage(new DataPacket(Message.CMD.SEND, userInput));

}

}

}

} catch (ConnectException e) {

Message.printLog(Message.logType.ERROR, "ChatClient-ClientStart:ConnectException!", true);

e.printStackTrace();

} catch (SocketException e) {

Message.printLog(Message.logType.ERROR, "服务器异常!", true);

System.exit(0);

} catch (IOException e) {

Message.printLog(Message.logType.ERROR, "ChatClient-ClientStart:IOException!", true);

e.printStackTrace();

}

}

}

class ClientReceiveMessageThread implements Runnable {

private ObjectInputStream in = null;

private String clientName = null;

public ClientReceiveMessageThread(ObjectInputStream in, String name) {

this.in = in;

this.clientName = name;

}

public int HandleReceiveMsg(Object data) throws IOException {

DataPacket dataPacket = (DataPacket) data;

switch (dataPacket.cmd) {

case LOGIN:

case SEND:

case SENDALL:

Message.printMessage(dataPacket.msg);

break;

}

return 0;

}

@Override

public void run() {

Object data;

try {

while ((data = in.readObject()) != null) {

HandleReceiveMsg(data);

}

} catch (EOFException e) {

} catch (SocketException e) {

Message.printLog(Message.logType.ERROR, "服务器异常!", true);

System.exit(0);

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

四.共用的类

Message.java

import java.text.SimpleDateFormat;

import java.util.Date;

public class Message {

// 是否打开debug输出

private static boolean debug = false;

// 设定日期时间格式

public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyy-MM-dd hh:mm:ss");

public static enum logType {

ERROR,

INFO,

WARN,

DEBUG,

};

public static enum CMD {

LOGIN,

SEND,

SENDALL,

}

public static void printLog(logType type, String msg, boolean newLine) {

if( debug == true || type != logType.DEBUG ) {

StringBuilder sb = new StringBuilder(128);

sb.append("[").append(type).append("]").append(msg);

if (newLine)

System.out.println(sb);

else

System.out.print(sb);

}

}

public static void printMessage(String msg) {

StringBuilder sb = new StringBuilder(1024);

sb.append("[").append(dateFormat.format(new Date())).append("]").append(msg);

System.out.println(sb);

}

}

DataPacket.java

import java.io.Serializable;

public class DataPacket implements Serializable {

/**

* 自动生成的UID

*/

private static final long serialVersionUID = -5366828169862565011L;

public Message.CMD cmd;

public String msg;

public DataPacket(Message.CMD cmd, String msg) {

this.cmd = cmd;

this.msg = msg;

}

}

java tcp 多人聊天_Java TCP简易多人聊天室内相关推荐

  1. JAVA 局域网聊天_java实现简易局域网聊天功能

    本文实例为大家分享了java使用udp模式编写聊天程序的具体代码,供大家参考,具体内容如下 java代码: /* 使用udp模式,编写一个聊天程序 有发送和接收数据2部分, 一个线程接收,一个线程发送 ...

  2. java 多人聊天_java编程实现多人聊天室功能

    导读热词 本文实例为大家分享了java实现多人聊天室的具体代码,供大家参考,具体内容如下 程序源代码及运行截图: server.java //server.java package Socket; i ...

  3. java模拟三人爬山_java笔记——模拟多人徒步爬山例子

    模拟多人徒步爬山,使用多线程模拟多人徒步爬山训练要点,使用任意一种方式创建线程,使用 Thread.sleep()方法设置线程休眠.需求说明:每个线程代表一个人可设置每人爬山速度每爬完 100 米显示 ...

  4. android socket 简易聊天室 java服务器_利用Socket制作一个简易的Android聊天室

    首先制作一个客户端,界面如下: 使用方法:启动后,首先在登录编辑框输入一个昵称,然后点击登录,上面灰色区域是聊天窗,其中会显示你的登录提示,显示其他人发的消息.在的登录成功后,可以在下面的发送编辑框内 ...

  5. java超级简单贪吃蛇_java实现简易贪吃蛇游戏

    本文实例为大家分享了java实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 1.封装贪吃蛇身体,抽象出贪吃蛇结点类Node,结点用ArrayList存储 import java.awt.*; pu ...

  6. java消费者和生产者模型_Java实现简易生产者消费者模型过程解析

    一.概述 一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程.当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完. 需要注意的是,有可能出现 ...

  7. java 多收件人抄送人_JAVA Mail多抄送人有抄送内容亲测可用

    ? ? ? 大周一的,上班没带耳机 pom文件依赖 com.sun.mail javax.mail 1.5.6 com.sun.mail smtp 1.5.2 jar compile com.sun. ...

  8. java 网络编程 聊天_Java——网络编程(实现基于命令行的多人聊天室)

    目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模 ...

  9. Java实现聊天室(TCP)

    用Java实现一个多人聊天室(TCP) 之前版本的聊天室比较简陋,这个版本我又加了些功能,看上去可能会好一点.该程序只是作为巩固理论知识的训练,所以会有很多考虑不周到的地方,请不要介意! 目录 用Ja ...

  10. Java Socket实现简易多人聊天室传输聊天内容或文件

    Java Socket实现简易多人聊天室传输聊天内容或文件 Java小练手项目:用Java Socket实现多人聊天室,聊天室功能包括传输聊天内容或者文件.相比于其它的聊天室,增加了传输文件的功能供参 ...

最新文章

  1. ECCV 2020 论文大盘点-6D 位姿估计篇
  2. android构建过程
  3. java2期末考试试题及答案_《JAVA语言程序设计》期末考试试题及答案(2)
  4. 为什么赚不到90后00后的钱?
  5. 第三方网站调用微信公众号的图片被禁止
  6. polar函数--Matplotlib
  7. php100视频教程(全集)
  8. wi ndows防火墙,WinXP自带防火墙设置详细讲解
  9. DPCM差分预测编码原理及实现
  10. MAX30102学习笔记(下)
  11. ubuntu 强制删除文件夹
  12. ai俄罗斯方块java_俄罗斯方块 AI 算法讲解
  13. 如何解决MathType公式与文字不在同一行问题---已解决
  14. php eot,php中理解print的EOT分界符
  15. 用Session记录实现页面数据的关联
  16. 目前得前端框架都有哪些?
  17. error: server certificate verification failed 问题
  18. 会玩,有人用 Python 模拟导弹防御!
  19. (第二章)OpGL超级宝典学习:创建我们第一个OpenGL程序,绘制一个点和三角形
  20. 手机CMWAP上网设置(完全版)

热门文章

  1. mysql查询各类课程的总学分_关于SQL练习2的一些写法。。。查询选修人数超过2人且成绩都在60分以上的课程 查询选修张老师讲授所有课程的学生 计算并填写学生获得的总学分...
  2. medusa安装和简单使用
  3. 图像艺术风格化 Neural-Style
  4. cmd命令行怎样运行python,在CMD命令行中运行python脚本的方法
  5. 华东师大二月月赛游记
  6. 数据挖掘概念与技术——读书笔记(1)
  7. 解码M3U8在线流视频AES-128解密TS合并到MP4
  8. Linux服务器CPU性能模式
  9. 古代诗词哲理名句赏析
  10. 龙芯电脑开启串口的console控制台配置