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