多人聊天室(Java)
第1部分 TCP和UDP
TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全;常用于一般不要求速度和需要准确发送消息的场合。
UDP:是一种不可靠的传输协议,常用于视频直播、游戏等及时性比较强的场景。
进行相关编程可以查询API手册。
第2部分 多人聊天室
下面是利用Java的TCP协议的API实现多人聊天室的案例代码:
服务端:
运行在服务端的SeverSocket主要负责:
1 向系统申请服务端口号,客户端是通过这个端口号和IP地址与之连接的;端口号一般取四千之一万之间,因为其余有的已经绑定系统系统应用和主流应用程序,最常用的便是8088。
2 监听申请的服务端口号,当一个客户端通过该端口号尝试建立联系连接时,SeverSocket会在服务端创建一个Socket与客户端建立连接,服务端正对不同客户端建立多个Socket,利用多线程实现。
工作模块及过程:
服务器先初始化,包括申请端口号,和创建共享消息集合(可以用map,key是用户名,value是消息,私聊返回value值,广播则遍历value),另外创建增删和发送消息的方法;
创建处理客户端交互的类,继承runnable,通过socket的getInetAdress和getHostAdress方法获取客户端计算机的信息,其start方法用来完成从一个客户端接收消息,并将其他客户端的消息返回给该客户端;
package chat;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List;/*** * 运行在服务端的SeverSocket主要负责;* 1 向系统申请服务端口号客户端是通过这个端口号与之连接的* 2 监听申请的服务端口号,当一个客户端通过该端口号尝试建立联系连接时,* SeverSocket会在服务端创建一个Socket与客户端建立连接* 服务端正对不同客户端建立多个Socket* * @author KwinWei QQ:885251358**/ public class Server {public ServerSocket server;/** 用来保存客户端输出流的集合,*因为线程安全的也不和遍历互斥,要自己维护也可以保证安全*/private List<PrintWriter> allOut; //私聊可以用map,key为昵称,value是对应消息,广播则遍历value/**初始化 服务端*/public Server()throws Exception {/** 初始化的同时申请端口号*/server = new ServerSocket(8788);allOut = new ArrayList<PrintWriter>();}/*** 将给定的输出流存入共享集合* @param out*/private synchronized void addOut(PrintWriter out) {allOut.add(out);}/*** 将给定的输出流从共享集合中删除* @param out*/private synchronized void removeOut(PrintWriter out) {allOut.remove(out);}/*** 将给定的消息发送给所有客户端* @param out*/private synchronized void sendMessage(String message) {for(PrintWriter out : allOut) {out.println(message);}}/*服务端开始工作的方法* */public void start() {try {/** ServerSocket的accept的方法* 是一个阻塞的方法,作用是监听服务端口号,知道一个客户端;连接并创建一个Socket,使用该Socket* 即可与刚才链接的客户端进行交互*/while(true) {System.out.println("等待客户端连接...");Socket socket = server.accept();System.out.println("一个客户端连接了!");/** 启动一个线程,来完成与该客户端的交互*/ClientHandler handler= new ClientHandler(socket);Thread t = new Thread(handler);t.start(); }} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {try {Server server = new Server();server.start();} catch (Exception e) {e.printStackTrace();System.out.println("服务端建立联系失败!");}}/***该线程负责处理一个客户端的交互* */class ClientHandler implements Runnable{/** 该线程处理的客户端的Socket*/private Socket socket ;// 客户端的地址信息,区分不同客户端private String host;//用户的昵称private String nickName;public ClientHandler(Socket socket) {this.socket = socket;/** 通过Socket可以获取远端计算机的地址信息*/InetAddress address = socket.getInetAddress();//获取IP地址host = address.getHostAddress();}public void run() {PrintWriter pw = null;try {/** Socket 提供的方法* InputStream getInputStream()* 该方法可以获取一个输入流,从该方法读取的数据就是从远端计算机发送来的 */InputStream in = socket.getInputStream();InputStreamReader isr = new InputStreamReader(in,"UTF-8");BufferedReader br = new BufferedReader(isr);//首先读取一行字符串为昵称nickName = br.readLine();//System.out.println(host+"上线了");sendMessage(nickName+"上线了");/** 通过Socket创建输出流用于将消息发送给客户端*/OutputStream out = socket.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");pw = new PrintWriter(osw,true);/** 将该客户端对的输出流存入到共享集合中*/addOut(pw);String message = null;/** br.readLine()在读取客户户端发送过来的消息时,由于客户端断线,* 而操作系统的不同,这里读取后的结果不同:* 当windows的客户端断开时:br.readLine会抛出异常* 当linux的客户端断开时:br.readLine 会返回null*/while((message = br.readLine())!=null) {//System.out.println(host+"说:"+ message);//pw.println(host+"说:"+message);//广播消息sendMessage(nickName+"说:"+message);} } catch (Exception e) {}finally {/** 处理当前客户端断开后的逻辑*///将该客户端的输出流从共享集合中删除 removeOut(pw);//System.out.println(host+"下线了");sendMessage(nickName+"下线了");try {socket.close();} catch (IOException e) {e.printStackTrace();}} }}}
View Code
客户端:
package chat;import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner;/*** * @author KwinWei QQ:885251358**/ public class Client {/** 套接字* * 理解为电话,拨号,建立联系,麦克风说话,* socket输入和输出流,* 你输入流对应他输出流,你说话他听* 你输出流对应他输入流* * java,net.Socket;* 封装了TCP协议,使用它就可以基于某种TCP协议进行网络通信* Socket试运行在客户端的*/private Socket socket;public Client() throws Exception {/**实例化Socket的时候需要传入两个参数* 1 IP:127.0.0.1或localhost本机;* 2 端口:0-65535,听服务端的,区用网程序,* 一般使用四千以上一万以下,前四千被占用绑定主流应用程序等 * 通过Ip可以找到服务的那台计算机,通过端口号可以找到服务端计算机上服务端用程序* * 实例化Socket的过程就是连接的过程,若远端计算机没有响应会抛出异常* */System.out.println("正在连接服务端...");socket = new Socket("localhost",8788);System.out.println("已经和服务端建立联系");}/** 启动客户端的方法*/public void start() {try {Scanner scanner = new Scanner(System.in);/** 先要求用户创建一个昵称*///System.out.println("");String nickName = null;while(true) {System.out.println("请用户输入用户名");nickName = scanner.nextLine();if(nickName.length()>0) {break;}System.out.println("输入有误");}System.out.println("欢迎你"+nickName+"!开始聊天吧!");/*socket 提供的方法:* OutputStream getOutStream* 获取一个字节输出流,通过该流写出的数据会被发送至远端计算机。*/OutputStream out = socket.getOutputStream();OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");PrintWriter pw = new PrintWriter(osw,true); //不能指明字节流,所以要加一个转换流,第二参数为true会行刷新//先将昵称发给服务器 pw.println(nickName);/** 启动读取服务端发送过来消息的线程*/ServerHandler handler = new ServerHandler();Thread t = new Thread(handler);t.start();/** 将字符串发送至服务端,加上行刷新,说一句发一句* 否则需要用 flush()强制写出*/while(true) {pw.println(scanner.nextLine());//pw.flush(); }} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {try {Client client = new Client();client.start();}catch(Exception e) {e.printStackTrace();System.out.println("客户端启动失败!");}}/** 该线程用来读取服务器端发送来的消息,并输出到客户端控制台显示*/class ServerHandler implements Runnable {public void run() {try {InputStream in = socket.getInputStream();InputStreamReader isr = new InputStreamReader(in,"UTF-8");BufferedReader br = new BufferedReader(isr);String message = null;while ((message = br.readLine())!=null) {System.out.println(message);}} catch (Exception e) {}}}}
View Code
转载于:https://www.cnblogs.com/kwinwei/p/10575144.html
多人聊天室(Java)相关推荐
- java 网络编程 聊天_Java——网络编程(实现基于命令行的多人聊天室)
目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络编程 6.基于TCP的多线程的聊天室的实现 1.ISO和TCP/IP分层模 ...
- Java——网络编程(实现基于命令行的多人聊天室)
2019独角兽企业重金招聘Python工程师标准>>> 目录: 1.ISO和TCP/IP分层模型 2.IP协议 3.TCP/UDP协议 4.基于TCP的网络编程 5.基于UDP的网络 ...
- Java NIO SocketChannel+Buffer+Selector 详解(含多人聊天室实例)
一.Java NIO 的核心组件 Java NIO的核心组件包括:Channel(通道),Buffer(缓冲区),Selector(选择器),其中Channel和Buffer比较好理解 简单来说 N ...
- java socket多人聊天室_如何运用Java socket实现多人聊天室功能
如何运用Java socket实现多人聊天室功能 导语:如何运用Java socket实现多人聊天室功能呢?下面是小编给大家提供的代码实现,大家可以参考阅读,更多详情请关注应届毕业生考试网. 目录结构 ...
- java tcp多人聊天室
TCP的多人聊天室 上次写了一个只能两个人通信的TCP,这次写了个可以多人聊天的,利用多线程实现. 设计模式: 服务端:首先运行服务器,然后启动一个专门处理客户端消息的线程,然后监听是否有客户端连接, ...
- Java Socket实现简易多人聊天室传输聊天内容或文件
Java Socket实现简易多人聊天室传输聊天内容或文件 Java小练手项目:用Java Socket实现多人聊天室,聊天室功能包括传输聊天内容或者文件.相比于其它的聊天室,增加了传输文件的功能供参 ...
- Java NIO Selector详解(含多人聊天室实例)
一.Java NIO 的核心组件 Java NIO的核心组件包括:Channel(通道),Buffer(缓冲区),Selector(选择器),其中Channel和Buffer比较好理解 简单来说 NI ...
- java仿qq聊天系统 多人聊天室
目录 项目介绍 项目截图 服务器与客户端 新用户注册 注册新账号成功 进入聊天室 多人在线 选择发送文件 文件接收提醒 项目代码参考 服务器入口程序 服务器请求处理 原理解析 服务器多人网络连接: 如 ...
- 【Java课程设计】仿QQ多人聊天室(基于TCP协议与JavaSwing)附下载
仿QQ多人聊天室 下载地址:链接:https://pan.baidu.com/s/1dLFjSxwTA4gL5lI0B4UGuQ 提取码:2qs0 有两个项目,分别是服务器chatterServer ...
最新文章
- mybaits十四:使用if和where标签构建动态sql
- python邮件图片加密_Python爬虫如何应对Cloudflare邮箱加密
- 数据结构:排序算法之堆排序和选择排序
- Eclipse Pydev 技巧汇编
- python消息队列celery_python异步任务神器celery
- BAT大牛这样搞Python,真是绝了
- 字符串 -- 将整数字符串转换为成整数值 -- 图解
- JSARToolKit5文档翻译
- java基础总结06-常用api类-System类常用方法
- 批处理从入门到精通_DOS/BAT
- LeetCode:459.重复的子字符串 Python3 | 判断输入的字符串是不是可以由子串多次重复构成
- Transform.rotation所见非所得
- 【模拟电路】温度对器件特性的影响
- 使用docer创建spring boot镜像
- 打孔的问题和打孔的位置
- 2016届阿里实习生java研发岗一面二面三面四面经验分享
- 如何扫描图片变成文字?手把手教你转换操作
- 【陈工笔记】# 同步网络和异步网络的理解 #
- 洛谷刷题笔记 奥运奖牌计数
- 一种电子病历系统软件框架思想——B/S与C/S混合架构