聊天软件服务器端
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://sophi.blog.51cto.com/340461/66383 |
import java.net.*; //import java.util.HashMap; import java.util.LinkedList; import java.util.List; //import java.util.Map; import java.io.*; public class Server { List<ClientServer> allClients = new LinkedList<ClientServer>(); ServerSocket server = null; boolean started = false; ClientListenner cl = null; //////////////////////////客户端Control + C 时发生NullPointerException,在线程ClientServer处 public static void main(String[] args) { new Server().start(); } /* * 服务器端构造函数 * 将监听接口绑定到本地端口8888处 */ public Server(){ try { server = new ServerSocket(8888); } catch (BindException e) { System.out.println("端口使用中"); System.out.println("请关掉相关程序并重新运行服务器!"); System.exit(0); } catch (IOException e) { e.printStackTrace(); System.exit(0); } } /* * 服务器启动函数 */ public void start() { System.out.println("Server Starts!"); started = true; cl = new ClientListenner(server); cl.start(); readCommand(); } /* * 服务器关闭函数 */ public void shutdown() { started = false; cl.close(); System.out.println("server shutdown"); } /* * 读取控制台输入命令函数 */ public void readCommand() { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = null; try{ while(started){ str = br.readLine(); excuteCommand(str); } } catch (NullPointerException e){/////////////Control+C时发生的异常 System.out.println("服务器中断"); } catch (IOException e) { e.printStackTrace(); } finally { try{ br.close(); } catch (IOException e1){ e1.printStackTrace(); } } } /* * 执行控制台命令函数 */ public void excuteCommand(String command) { if (command.toLowerCase().equals("useramount")) { System.out.println(getUserAmount()); } else if (command.toLowerCase().equals("usernames")) { System.out.println(getAllUserName()); } else if (command.toLowerCase().equals("userinfo")) { System.out.println(getUserInfo()); } else if (command.toLowerCase().equals("help")) { System.out.println(getHelp()); } else if (command.toLowerCase().equals("shutdown")){ shutdown(); } } /* * 获取当前服务器在线人数函数 */ public String getUserAmount() { return "当前在线用户人数为: " + allClients.size() + "\n"; } /* * 获取当前服务器在线用户的名字 */ public String getAllUserName(){ StringBuffer sb = new StringBuffer(); sb.append("当前在线用户是:"); sb.append("\n"); for (int i = 0; i < allClients.size(); i++) { sb.append(allClients.get(i).userName); } return sb.toString(); } /* * 获取当前服务器在线用户的信息 * 包括用户个数和用户姓名 */ public String getUserInfo() { StringBuffer sb = new StringBuffer(); sb.append(getUserAmount()); sb.append(getAllUserName()); return sb.toString(); } /* * 提供服务器命令信息 */ public String getHelp() { StringBuffer sb = new StringBuffer(); sb.append("useramount 显示当前在线用户人数\n"); sb.append("usernames 显示当前在线用户的名字\n"); sb.append("userinfo 显示当前在线用户的人数及姓名"); return sb.toString(); } /* * 监听客户端连接线程 * 为每一个新连接的客户端提供一个服务器线程 */ class ClientListenner extends Thread { ServerSocket s = null; public ClientListenner(ServerSocket s) { this.s = s; } @Override public void run() { try{ while (started) { Socket c_server = s.accept(); ClientServer cs = new ClientServer(c_server); allClients.add(cs); System.out.println(cs.userName + "登录"); new Thread(cs).start(); } } catch (SocketException e){ System.out.print("");//////////////////客户端关闭的时候发生异常 } catch (IOException e){ e.printStackTrace(); } } public void close() { try { started = false; if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } /* * 服务器服务线程类 * 接受客户端的输入,并将获得到信息发送到所有的客户端 */ class ClientServer implements Runnable { Socket c_server = null; ClientServer cs = null; boolean connected = false; DataOutputStream dout = null; DataInputStream din = null; String userName = null; /* * 构造函数 * 初始化从客户端获得的socket、建立服务器与客户端的连接、初始化输入输出流 */ public ClientServer(Socket s) { c_server = s; connected = true; try { din = new DataInputStream(s.getInputStream()); dout = new DataOutputStream(s.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } register(receiveMessage()); } /* * 消息发送函数 * 向客户端发送消息 */ public void sendMessage(String message) { try { dout.writeUTF(message); dout.flush(); } catch (IOException e) { e.printStackTrace(); } } /* * 消息接受函数 * 从客户端接受消息 */ public String receiveMessage() { String message = null; try{ message = din.readUTF(); } catch (EOFException e){ System.out.println("客户端中断!"); } catch (SocketException e){ System.out.print("");//////////////////客户端关闭的时候发生异常 } catch (IOException e){ e.printStackTrace(); } return message; } @Override public void run() { String str = null; sendMessage("server says:hello,I am the server!"); while (connected) { str = receiveMessage(); interpret(str); } close(); } /* * 服务线程类关闭函数 * 关闭相关输入输出流、socket */ public void close() { try { if (dout != null) dout.close(); if (din != null) din.close(); if (c_server != null) c_server.close(); if (allClients.contains(this)) allClients.remove(this); } catch (IOException e) { e.printStackTrace(); } } /* * 消息解释函数 * 根据消息类型选择执行相关操作 */ public void interpret(String str) { boolean bToAll = true; switch (strType(str)) { case 0: sendToClient(bToAll, str); break; case 1: bToAll = changePeople(str); break; case 2: excuteUserCommand(str); break; default: break; } } /* * 注册函数 * 服务器段记录登录用户名 */ private void register(String name){ userName = name; } /* * 命令执行函数 * 根据客户端发送过来的指令执行相关操作 */ private void excuteUserCommand(String str){ String command = str.substring(1); if (command.equals("userinfo")){ sendMessage(getUserInfo()); } else if(command.equals("help")){ sendMessage(getHelp()); } else if(command.equals("bye")){ connected = false; System.out.println(userName + "退出了"); allClients.remove(this); } } /* * 消息转发对象转换函数 * 选择单对单发送消息,或者群发消息 */ private boolean changePeople(String str) { String name = str.substring(1); if (name.equals("all")) { return true; } else { for (int i = 0; i < allClients.size(); i++) { if (name.equals(allClients.get(i).userName)) { cs = allClients.get(i); return false; } } } return true; } /* * 消息解释函数 * 根据消息起始字符调用返回整型值 * @return 1 表示对象转换 * @return 2 表示获取服务器信息 * @return 0 表示正常消息发送语句 */ private int strType(String str){ if (str.startsWith("-")) return 1; else if(str.startsWith("?")) return 2; else return 0; } /* * 消息发送函数 * 根据传入的参数,将消息传给群发或者发送给指定客户端 */ private void sendToClient(boolean bToAll,String str) { if (bToAll) { for (int i = 0; i < allClients.size(); i++) { allClients.get(i).sendMessage(this.userName + " says: " + str); } } else { cs.sendMessage(cs.userName + " says: " + str); } } } } 本文出自 ““技”忆” 博客,请务必保留此出处http://sophi.blog.51cto.com/340461/66383 本文出自 51CTO.COM技术博客 |


huixianmaomao
博客统计信息
热门文章
最新评论
友情链接