java socket 通信,简易聊天功能,
参考:http://www.cnblogs.com/feijian/p/4461087.html
服务端:
package com.lw.socket.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.LinkedList; import java.util.List; public class ChatServer extends ServerSocket { private static final int SERVER_PORT = 8000; private static final String KEY = "key"; private static boolean isPrint = false;// 是否输出消息标志 private static List<String> user_list = new ArrayList<>();// 登录用户集合 private static List<ServerClientThread> thread_list = new ArrayList<ServerClientThread>();// 服务器已启用线程集合 private static LinkedList<String> message_list = new LinkedList<String>();// 存放消息队列 /** * 创建服务端Socket,创建向客户端发送消息线程,监听客户端请求并处理 */ public ChatServer() throws IOException { super(SERVER_PORT);// 创建ServerSocket new PrintOutThread();// 创建向客户端发送消息线程 new ServerReadThread();// 创建向客户端发送消息线程(服务端输入数据推送到各客户端) try { while (true) {// 监听客户端请求,启个线程处理 Socket socket = accept(); new ServerClientThread(socket); } } catch (Exception e) { e.printStackTrace(); } finally { close(); } } /** * 监听是否有输出消息请求线程类,向客户端发送消息 */ class PrintOutThread extends Thread { public PrintOutThread() { start(); } @Override public void run() { while (true) { if (isPrint) {// 将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。 String message = message_list.getFirst(); for (ServerClientThread thread : thread_list) { thread.sendMessage(message); } message_list.removeFirst(); isPrint = message_list.size() > 0 ? true : false; } } } } /** * 服务器向各客户端发送数据的线程 */ class ServerReadThread extends Thread { public ServerReadThread() { start(); } @Override public void run() { BufferedReader br = null; try { while (true) { System.out.println("服务端发送数据输入:"); br = new BufferedReader(new InputStreamReader(System.in)); String send = br.readLine(); DateFormat dateTimeformat = new SimpleDateFormat("HH:mm:ss"); String date = dateTimeformat.format(new Date()); message_list.addLast(date + "【系统消息】:" + send); isPrint = true; } } catch (Exception e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { e.printStackTrace(); } } } } /** * 服务器线程类 */ class ServerClientThread extends Thread { private Socket client; private PrintWriter writer; private BufferedReader reader; private String name; public ServerClientThread(Socket s) throws IOException { client = s; writer = new PrintWriter(client.getOutputStream(), true); reader = new BufferedReader(new InputStreamReader(client.getInputStream())); String read = reader.readLine(); if(KEY.equals(read)) { writer.println("成功连上聊天室,请输入你的名字:"); start(); } } @Override public void run() { try { int flag = 0; String line = reader.readLine(); while (!"byeClient".equals(line)) { // 查看在线用户列表 if ("showuser".equals(line)) { writer.println(this.listOnlineUsers()); line = reader.readLine(); } // 第一次进入,保存名字 if (flag++ == 0) { name = line; user_list.add(name); thread_list.add(this); writer.println(name + "你好,可以开始聊天了..."); this.pushMessage("【" + name + "】进入聊天室..."); } else { this.pushMessage("【" + name + "】 say : " + line); } line = reader.readLine(); } writer.println("byeClient"); } catch (Exception e) { e.printStackTrace(); } finally {// 用户退出聊天室 try { client.close(); } catch (IOException e) { e.printStackTrace(); } thread_list.remove(this); user_list.remove(name); pushMessage("【" + name + "】退出了聊天室"); } } // 放入消息队列末尾,准备发送给客户端 private void pushMessage(String msg) { DateFormat dateTimeformat = new SimpleDateFormat("HH:mm:ss"); String date = dateTimeformat.format(new Date()); message_list.addLast(date + msg); isPrint = true; } // 向客户端发送一条消息 private void sendMessage(String msg) { writer.println(msg); } // 统计在线用户列表 private String listOnlineUsers() { String s = "--- 在线用户列表 ---\015\012"; for (int i = 0; i < user_list.size(); i++) { s += "[" + user_list.get(i) + "]\015\012"; } s += "--------------------"; return s; } } public static void main(String[] args) { try { new ChatServer().close();// 启动服务端 } catch (IOException e) { e.printStackTrace(); } } }
客户端:
package com.lw.socket.client; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class ChatClient extends Socket { private static final String SERVER_IP = "127.0.0.1"; private static final int SERVER_PORT = 8000; private static final String PASSWORD = "pwd"; private static final String KEY = "key"; private Socket client; private PrintWriter writer; private BufferedReader reader; /** * 与服务器连接,并输入发送消息 */ public ChatClient() throws Exception { super(SERVER_IP, SERVER_PORT); client = this; writer = new PrintWriter(client.getOutputStream(), true); reader = new BufferedReader(new InputStreamReader(client.getInputStream())); new readLineThread(); System.out.println("输入正确的密码连接服务器"); while(true) { BufferedReader readerIn = new BufferedReader(new InputStreamReader(System.in)); String input = readerIn.readLine(); if(PASSWORD.equals(input)) { writer.println(KEY); break; } else { System.out.println("输入错误,请重新输入!"); } } while (true) { reader = new BufferedReader(new InputStreamReader(System.in)); String input = reader.readLine(); writer.println(input); } } /** * 用于监听服务器端向客户端发送消息线程类 */ class readLineThread extends Thread { private BufferedReader buff; public readLineThread() { try { buff = new BufferedReader(new InputStreamReader(client.getInputStream())); start(); } catch (Exception e) { e.printStackTrace(); } } @Override public void run() { try { while (true) { String result = buff.readLine(); if ("byeClient".equals(result)) {// 客户端申请退出,服务端返回确认退出 break; } else {// 输出服务端发送消息 System.out.println(result); } } reader.close(); writer.close(); client.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { try { new ChatClient().close();// 启动客户端 } catch (Exception e) { e.printStackTrace(); } } }