服务端
package study_05;
/*
*
* 目标:
* 1 读写分离
* 2 封装
*
*
*
*/
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiThreadCheatServerV2 {
public static void main(String[] args) throws IOException {
System.out.println("------Server--------");
ServerSocket server = new ServerSocket(9999);//开启服务器
while (true) {//循环接收客户端
Socket client = server.accept();//阻塞接收
System.out.println("有客户端连接上");
new Thread(new Channel(client)).start();//开启新得与客户端联系的通道
}
}
static class Channel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning = true;
public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
release();//报错则释放资源
}
}
//接受消息
private String recieve() {
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
// TODO Auto-generated catch block
release();
}
return msg;
};
//发送消息
private void send(String msg) {
try {
System.out.println(msg);
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
release();
}
};
//释放资源
private void release() {
isRunning = false;
IOutils.close(dis,dos,client);
}
@Override
public void run() {
while (isRunning) {
String msg = recieve();
if (!msg.equals("")) {
send(msg);
}
}
}
}
}
客户端
接收消息类
package study_05;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class Recieve implements Runnable{
private Socket client;
private DataInputStream dis;
private boolean isRunning = true;
public Recieve(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (isRunning) {
getString();
}
}
private String getString() {
String msg = "";
try {
msg = dis.readUTF();
System.out.println(msg);
} catch (IOException e) {
release();
}
return msg;
}
private void release() {
isRunning = false;
IOutils.close(dis,client);
}
}
发送消息类
package study_05;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/*
*
* 发送消息类
*
*/
public class Send implements Runnable{
private DataOutputStream dos;
private Socket client;
private boolean isRunning = true;
private BufferedReader reader;
public Send(Socket client) {
this.client = client;
reader = new BufferedReader(new InputStreamReader(System.in));
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
release();
}
}
//从控制台接收消息
private String getMsgFromConsole() {
try {
return reader.readLine();
} catch (IOException e) {
release();
}
return "";
}
//发送消息
private void sendMsg(String msg) {
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
release();
}
}
@Override
public void run() {
while (isRunning) {
String msg = getMsgFromConsole();
if (!msg.equals("")) {//消息不为空
sendMsg(msg);//发送消息
}
}
}
//释放资源
private void release() {
isRunning = false;
IOutils.close(dos,client);
}
}
客户端
package study_05;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/*
*
* 使用OOP思想 使用多线程实现多个客户端的在线聊天
*
*/
public class MultiThreadCheatClientV2 {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("------Client--------");
Socket client = new Socket("localhost",9999);
new Thread(new Send(client)).start();//开启发送消息线程
new Thread(new Recieve(client)).start();//开启接收消息线程
}
}
工具类
package study_05;
import java.io.Closeable;
import java.io.IOException;
public class IOutils {
//释放资源
///...表示接受多个参数 只要继承了Closeable接口都支持关闭
//例如class ServerSocket implements java.io.Closeable
public static void close(Closeable... targets) {
for (Closeable target : targets) {
try {
target.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}