1.客户端
/** * 聊天室客户端 */ public class Client { /* * java.net.Socket 套接字 * Socket封装了TCP协议传输数据的细节,使得我们可以通过两条流的读写完成与远端计算 * 机的数据交互 */ private Socket socket; /** * 构造方法,用来初始化客户端 */ public Client() { try { /* * 实例化Socket的过程就是连接服务端的过程. * 参数1:服务端的IP地址 * 参数2:服务端程序打开的端口 * * 我们通过IP可以找到网络上的服务端所在计算机,通过端口可以找到该计算机上运行 * 的服务端应用程序从而建立连接. */ System.out.println("正在连接服务端..."); socket = new Socket("localhost",8088); System.out.println("已连接服务端!"); } catch (Exception e) { e.printStackTrace(); } } /** * 客户端开始工作的方法 */ public void start() { try { Scanner scanner = new Scanner(System.in); /* * Socket提供的方法: * OutputStream getOutputStream() * 通过该方法获取的输出流写出的字节会通过网络发送给远端计算机. */ OutputStream out = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8"); BufferedWriter bw = new BufferedWriter(osw); PrintWriter pw = new PrintWriter(bw,true); while(true) { String message = scanner.nextLine(); pw.println(message); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Client client = new Client(); client.start(); } }
2.服务端
/** * 聊天室服务端 */ public class Server { /* * 运行在服务端的ServerSocket主要有两个作用 * 1:向系统申请服务端口,客户端就是通过这个端口与服务端程序建立连接的 * 2:监听服务端口,一旦一个客户端建立连接就会返回一个Socket实例,服务端就可以通过 * 这个Socket实例与该客户端交互了. */ private ServerSocket server; public Server() { try { /* * 实例化ServerSocket时要指定申请的服务端口,如果该端口被系统的其他程序使用时会抛出异常. */ System.out.println("正在启动服务端..."); server = new ServerSocket(8088); System.out.println("服务端启动完毕!"); } catch (Exception e) { e.printStackTrace(); } } public void start() { try { /* * Socket accept() * 该方法是一个阻塞方法,调用后就"卡住了",此时开始等待客户端的连接,一旦一个客户端建立连接 * 此时该方法会立即返回一个Socket实例,通过这个Socket就可以与该客户端交互了. */ while(true) { System.out.println("等待客户端连接..."); Socket socket = server.accept(); System.out.println("一个客户端连接了!"); //启动一个线程处理该客户端交互 ClientHandler handler = new ClientHandler(socket); Thread t = new Thread(handler); t.start(); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Server server = new Server(); server.start(); } /** * 该线程负责与指定客户端交互 */ private class ClientHandler implements Runnable{ private Socket socket; private String host;//记录客户端的IP地址 public ClientHandler(Socket socket) { this.socket = socket; //通过socket获取远端计算机地址信息 host = socket.getInetAddress().getHostAddress(); } public void run() { try { /* * InputStream getInputStream() * Socket的该方法获取的输入流读取的是远端计算机发送过来的字节 */ InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in,"UTF-8"); BufferedReader br = new BufferedReader(isr); String message = null; /* * 当客户端断开连接时,服务端这边readLine方法有两种情况: * 1:返回值为null,通常linux的客户端断开时会出现这种情况 * 2:直接抛出SocketException:connection reset */ while((message = br.readLine())!=null) { System.out.println(host+"说:"+message); } } catch (Exception e) { } } } }
原文:https://www.cnblogs.com/hello4world/p/12150976.html