java类似QQ的聊天室程序的实现(下)(服务器端程序)

来源:互联网 发布:dnf网络不稳定 编辑:程序博客网 时间:2024/04/29 16:29
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();}@Overridepublic 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();}}}}}

0 0
原创粉丝点击