java类似QQ的聊天室程序的实现(下)(服务器端程序)
2016-05-10 19:48
621 查看
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; /** * 聊天室客户端 * @author~~ */ public class Server { /* * java.net.ServerScoket * 运行在服务端的ServerSocket有两个作用 * 1:申请服务端口(客户端通过该端口与服务端建立链接) * 2 监听端口:一旦客户通过该端口链接后,会创建一个Scoket实例与该客户进行通讯 */ private ServerSocket server; // 保存所有客户端的流 private List<PrintWriter> allOut; public Server() throws IOException{ /* * 创建ServerScoket同时需要申请服务端口 * 这个端口不能与其他使用TCP协议的应用程序冲突 * 否测 会抛出异常 * */ server=new ServerSocket(8088); allOut =new ArrayList<PrintWriter>(); } private synchronized void addOut(PrintWriter pw){ /* * 将指定的客户端的输出流从共享的集合中删除 * @param pw */ allOut.add(pw); } private synchronized void removeOut(PrintWriter pw){ allOut.remove(pw); } /* * 广播消息 将给定的消息通过遍历共享集合将该消息发送给没有个客户端 */ private synchronized void sendMessagage(String message){ for(PrintWriter pw:allOut){ pw.println(message); } } public void start() throws IOException{ while(true){ System.out.println("等待客户端链接..."); /* * Socket accept() * serversocket提供了accept方法用来监听打开的服务端口 * 一旦一个客户端通过该端口请求时 就会创建一个socket并返回 * 通过该socket就可以与客户端进行交互了 * 该方法是一个阻塞方法 * 直到客户端连接才会有返回值 */ Socket socket=server.accept(); ClientHandler hander=new ClientHandler(socket); Thread t=new Thread(hander); t.start(); } } public static void main(String[] args) { try{ Server server=new Server(); server.start(); }catch(Exception e){ e.printStackTrace(); } } /* * 该类十一个线程的任务,负责与指定客户端进行交互 * */ private class ClientHandler implements Runnable{ /* * 当前线程需要需要处理的针对客户端socket */ private Socket socket; private String host; public ClientHandler(Socket socket){ this.socket=socket; InetAddress address=socket.getInetAddress(); host=address.getHostAddress(); } @Override public void run() { PrintWriter pw=null; try{ //sendMessagage(host+" 上线了"+allOut.size()+"人在线"); //System.out.println(host+"上线了!"); //创建输出流 用来将消息发送至客户端 OutputStream out=socket.getOutputStream(); OutputStreamWriter osw=new OutputStreamWriter(out,"UTF-8"); //PrintWriter pw=new PrintWriter(osw,true); pw=new PrintWriter(osw,true); //将该客户端的输出流存入共享集合 addOut(pw); sendMessagage(host+" 上线了"+allOut.size()+"人在线"); /* * InputStream getInputStream() * socket 提供的该方法可以获取一个输入流, * 通过该输入流可以读取远端计算机发送过来的数据 */ //Thread thead=Thread.currentThread(); InputStream in=socket.getInputStream(); InputStreamReader inr=new InputStreamReader(in,"UTF-8"); BufferedReader buf=new BufferedReader(inr); String message=null; while((message=buf.readLine())!=null){ /* * 使用br.readLine方法读取远端计算机发送过来的数据时,由于客户端操作系统不同,当断开连接时这里的反应也不相同。 * 当linux的客户端断开连接:会返回null * 当windows客户端断开时:会抛出异常 */ // System.out.println(host+"说:"+message); // pw.println(host+"说:"+message); sendMessagage(host+" 说 :"+message); //sendMessagage(host+) } }catch(IOException e){ e.printStackTrace(); } finally{ //客户端断开链接处理 //将噶客户端的输出流从从共享集合中删除 removeOut(pw); //System.out.println(host+"下线了"); sendMessagage(host+"下线了"+"还剩多少人在线"+allOut.size()); try{ socket.close(); }catch(IOException e){ e.printStackTrace(); } } } }}
相关文章推荐
- Spring加载properties文件的两种方式
- java 类似QQ的本地聊天室程序实现(上)(客户端程序)
- JAVA_SE使用反射机制new实例简例
- [Java视频笔记]day21
- java学习第一节
- 如何在windows安装Eclipse
- JDBC / Spring / MyBatis 性能比较
- 让Myeclipse10支持Mac OSX – Retina显示屏
- spring-data-solr:第一步.基本po类与schema.xml文件的对应
- 设置eclipse默认用户名
- java线程状态图;
- Java--类的继承--回合制对战游戏
- java中如何自定义线程
- java中static{}语句块详解
- Table of Contents - Spring
- java生成pdf文件的完善
- java中BeanWriter类
- java中进程和线程的区别
- JavaSE
- 系统里有Courier New字体 Eclipse没有这个字体选项