java tcp 多人聊天_Java TCP简易多人聊天室内
一.说明:
本例是一个简易的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简易多人聊天室内相关推荐
- JAVA 局域网聊天_java实现简易局域网聊天功能
本文实例为大家分享了java使用udp模式编写聊天程序的具体代码,供大家参考,具体内容如下 java代码: /* 使用udp模式,编写一个聊天程序 有发送和接收数据2部分, 一个线程接收,一个线程发送 ...
- java 多人聊天_java编程实现多人聊天室功能
导读热词 本文实例为大家分享了java实现多人聊天室的具体代码,供大家参考,具体内容如下 程序源代码及运行截图: server.java //server.java package Socket; i ...
- java模拟三人爬山_java笔记——模拟多人徒步爬山例子
模拟多人徒步爬山,使用多线程模拟多人徒步爬山训练要点,使用任意一种方式创建线程,使用 Thread.sleep()方法设置线程休眠.需求说明:每个线程代表一个人可设置每人爬山速度每爬完 100 米显示 ...
- android socket 简易聊天室 java服务器_利用Socket制作一个简易的Android聊天室
首先制作一个客户端,界面如下: 使用方法:启动后,首先在登录编辑框输入一个昵称,然后点击登录,上面灰色区域是聊天窗,其中会显示你的登录提示,显示其他人发的消息.在的登录成功后,可以在下面的发送编辑框内 ...
- java超级简单贪吃蛇_java实现简易贪吃蛇游戏
本文实例为大家分享了java实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 1.封装贪吃蛇身体,抽象出贪吃蛇结点类Node,结点用ArrayList存储 import java.awt.*; pu ...
- java消费者和生产者模型_Java实现简易生产者消费者模型过程解析
一.概述 一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程.当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完. 需要注意的是,有可能出现 ...
- java 多收件人抄送人_JAVA Mail多抄送人有抄送内容亲测可用
? ? ? 大周一的,上班没带耳机 pom文件依赖 com.sun.mail javax.mail 1.5.6 com.sun.mail smtp 1.5.2 jar compile com.sun. ...
- java 网络编程 聊天_Java——网络编程(实现基于命令行的多人聊天室)
目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模 ...
- Java实现聊天室(TCP)
用Java实现一个多人聊天室(TCP) 之前版本的聊天室比较简陋,这个版本我又加了些功能,看上去可能会好一点.该程序只是作为巩固理论知识的训练,所以会有很多考虑不周到的地方,请不要介意! 目录 用Ja ...
- Java Socket实现简易多人聊天室传输聊天内容或文件
Java Socket实现简易多人聊天室传输聊天内容或文件 Java小练手项目:用Java Socket实现多人聊天室,聊天室功能包括传输聊天内容或者文件.相比于其它的聊天室,增加了传输文件的功能供参 ...
最新文章
- ECCV 2020 论文大盘点-6D 位姿估计篇
- android构建过程
- java2期末考试试题及答案_《JAVA语言程序设计》期末考试试题及答案(2)
- 为什么赚不到90后00后的钱?
- 第三方网站调用微信公众号的图片被禁止
- polar函数--Matplotlib
- php100视频教程(全集)
- wi ndows防火墙,WinXP自带防火墙设置详细讲解
- DPCM差分预测编码原理及实现
- MAX30102学习笔记(下)
- ubuntu 强制删除文件夹
- ai俄罗斯方块java_俄罗斯方块 AI 算法讲解
- 如何解决MathType公式与文字不在同一行问题---已解决
- php eot,php中理解print的EOT分界符
- 用Session记录实现页面数据的关联
- 目前得前端框架都有哪些?
- error: server certificate verification failed 问题
- 会玩,有人用 Python 模拟导弹防御!
- (第二章)OpGL超级宝典学习:创建我们第一个OpenGL程序,绘制一个点和三角形
- 手机CMWAP上网设置(完全版)
热门文章
- mysql查询各类课程的总学分_关于SQL练习2的一些写法。。。查询选修人数超过2人且成绩都在60分以上的课程 查询选修张老师讲授所有课程的学生 计算并填写学生获得的总学分...
- medusa安装和简单使用
- 图像艺术风格化 Neural-Style
- cmd命令行怎样运行python,在CMD命令行中运行python脚本的方法
- 华东师大二月月赛游记
- 数据挖掘概念与技术——读书笔记(1)
- 解码M3U8在线流视频AES-128解密TS合并到MP4
- Linux服务器CPU性能模式
- 古代诗词哲理名句赏析
- 龙芯电脑开启串口的console控制台配置