简单聊天室(java版)
来源:互联网 发布:go桌面软件下载 编辑:程序博客网 时间:2024/04/30 03:00
这是本人从其他地方学习到的关于聊天室的一个模本,我从中截取了一部分关于客户端和服务端通信的Socket的内容。希望对大家对socket有个了解,我写的这些代码可以实现两人或多人在多台电脑上实现简单的对话。在运行时要先运行server(服务端),再运行client(客户端)。Windows获取自己电脑的ip需要再DOS(命令窗口)界面输入ipconfig或者再网络和共享中心已连接的网络查看详细信息。具体的代码如下
客户端代码
package talkRoom;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 ylg * */public class Client { //客户端用于与服务端通信的socket private Socket socket; /** *初始化客户端相关内容 */ public Client(){ try { /** * 实例化socket的过程就是连接的过程通常我们要传入两个参数 * 1:字符串,服务器的IP地址 * 2:整数,服务器端申请的端口号 * (serversocket创建时申请的端口号:8088) */ System.out.println("尝试连接"); //此处的localhost可以改为运行服务端的那台电脑的的ip地址这样就可以连在一起聊天了 //localhost指的是本机的ip socket =new Socket("localhost", 8088); System.out.println("连接成功"); } catch (Exception e) { e.printStackTrace(); } } /** * 客户端用于交互的方法 */ public void start(){ try { /** * 创建一个线程,用于读取服务器发过来的信息 */ Runnable hander=new GetMessageFromServerHandler(); Thread t=new Thread(hander); t.start(); /** * 客户端想向服务发送消息,通过socket花去输出流之后写出数据即可 */ OutputStream out=socket.getOutputStream(); /** * 向服务器发送字符串,我们可以将字节流转换为缓冲字符流输出PrintWrint * */ OutputStreamWriter osw=new OutputStreamWriter(out,"UTF-8"); /** * 发送一个字符串就应当立即写出,所以要自动行刷新 */ PrintWriter pw=new PrintWriter(osw,true); /** * 创建scanner,将控制台输入的字符串通过pw发送给服务器 */ String message=null; Scanner scanner=new Scanner(System.in); while(true){ message=scanner.nextLine(); pw.println(message); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Client client=new Client(); client.start(); } /** * 该线程的作用是让客户端可以读取服务器发送过来的信息 * @author ylg * */ class GetMessageFromServerHandler implements Runnable{ /** * 通过socket获取输入流,在转换为缓冲字符输入流 * 最后通过循环都读取服务端发送的每一行信息 */ 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) { } } }}
服务端代码(请先运行服务端)
package talkRoom;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.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 服务端 * @author ylg * */public class Server { /** * 用于与客户端连接的ServerSOocket */ private ServerSocket server; /** * 存放所有客户端的输入流,用于广播信息 */ private List<PrintWriter> allOut; /** * 线程池,用于控制服务端线程数量,并重用线程 */ private ExecutorService threadPool; /** * 构造方法,用于初始化服务器相关内容 * */ public Server(){ try { //初始化ServerSocket /** * 初始化时要求我们传入一个整数,这个整数表示端口号,客户端就是 * 通过这个端口号连接到服务端的 */ server=new ServerSocket(8088); /** * 初始化存放所有客户端输出流的家集合 */ allOut =new ArrayList<PrintWriter>(); //初始化线程池 threadPool=Executors.newFixedThreadPool(50); } catch (Exception e) { e.printStackTrace(); } } /** * 将给定的输出流存入共享集合中 * @param out */ private synchronized void addOut(PrintWriter out){ allOut.add(out); } /** * 从共享集合中删除给定的删除流 * @param out */ private synchronized void removeOut(PrintWriter out){ allOut.remove(out); } //还要遍历方法,并且三个操作集合的方法互斥 /** * 遍历所有的输出流将给定的字符串发送给所有客户端 * @param message 服务器接收到的消息 */ private synchronized void sendMsgToAllClient(String message){ for(PrintWriter pw:allOut){ pw.println(message); } } /** * 服务端开始工作的方法 */ public void start(){ try { /** * socket accept() * 该方法是一个阻塞方法,用于等待客户端的连接 * 一旦一个客户端连接上,该方法就会返回与该客户端通信socket */ System.out.println("等待客户端的连接..."); /** * 死循环的目的是一直监听不同客户端的连接 */ while(true){ Socket socket=server.accept(); System.out.println("一个客户端连接上了..."); /** * 当一个客户端连接后,启动一个线程,将该客户端的socket传入, * 是该线程与客户端通信 */ Runnable clientHandler=new ClientHandler(socket);// Thread t=new Thread(clientHandler);// t.start(); threadPool.execute(clientHandler); } } catch (Exception e) { }finally { } } public static void main(String[] args) { Server server =new Server(); server.start(); } /** * 该线程的作用是与给定的客户端Socket进行通信 * @author ylg * */ class ClientHandler implements Runnable{ /** * 当前线程用于交流的指定客户端的Socket */ private Socket socket; /** * 创建线程体时将交互的Socket传入 * @param socket */ public ClientHandler(Socket socket){ this.socket=socket; } /** * 定义在try外面是因为finally中要引用 */ PrintWriter pw=null; public void run(){ try { /** * 通过socket获取输出流,用于将信息发送给客户端 */ OutputStream out=socket.getOutputStream(); OutputStreamWriter osw=new OutputStreamWriter(out, "utf-8"); pw=new PrintWriter(osw,true); /** * 将该客户端的输出流存入共享集合 */ addOut(pw); /** * 通过连接上的客户端的socket获取输入流来读取客户端发送过来的信息 */ InputStream in=socket.getInputStream(); InputStreamReader isr=new InputStreamReader(in,"UTF-8"); /** * 包装为缓冲流字符输入流,可以按行读取字符串 */ BufferedReader br=new BufferedReader(isr); String message=null; while((message=br.readLine())!=null){ //将当前的发送的消息广播给所有客户端 sendMsgToAllClient(message); /* //System.out.println("客户端说: "+message); //将读取到的信息发送给客户端 pw.println(message);*/ //在服务端上显示 System.out.println(message); } } catch (Exception e) { }finally{ /** * linux客户端若断开连接,服务端会读取到null * windows的客户端断开连接,服务端会抛出异常 * 所以finally是我们最后处理的最佳地点 */ System.out.println("客户端下线"); /** * 当客户端断开后,将其输出流从共享集合中删除 */ removeOut(pw); /** * 输出在线人数 */ System.out.println("当前在线人数"+allOut.size()); /** * 不同分别关闭输入流与输出流 * 关闭socket即可,因为这两个流都是从socket获取的,就好比打电话 * 我们最终挂断电话就自然断开了麦克风和听筒一样 */ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
看不懂的可以在下方留言
1 0
- 简单聊天室(java版)
- java通信聊天室简单命令行版
- 简单的java聊天室
- java简单聊天室
- java简单的聊天室
- java实现简单聊天室
- java简单聊天室
- java的简单聊天室程序
- 一个简单的java聊天室
- java Socket实现简单聊天室
- java简单的控制台聊天室
- Java编写简单的聊天室
- Java NIO实现简单聊天室(GUI版)
- 用JAVA写个简单的聊天室-单人版
- JAVA版聊天室
- Java写的简单Socket聊天室
- java基于socket tcp的简单聊天室
- java写的简单的聊天室
- @SerializedName注解
- [Leetcode] 98. Validate Binary Search Tree 解题报告
- LVS:三种负载均衡方式比较+另三种负载均衡方式
- Java实例化的几种方式
- js实现发送短信验证码后的倒计时功能(无视页面刷新)
- 简单聊天室(java版)
- java用递归实现的数组排列算法
- ImportError: No module named sklearn model_selection
- 4月21日
- 亿级Web系统搭建:单机到分布式集群
- centos7 安装jsoncpp
- struct protoent函数结构
- SpringMVC之文件上传与下载
- Tomcat优化之配置线程池