Java基础ServerSocket、Socket服务端客户端通信的示例,从简单到伪异步逐渐升级。
简单示例
最加单的示例,客户端向服务端发送一个消息就结束。
服务端代码:
/**
* 服务端
*
* @Author wanglingqiang
* @Date 2020/7/3 下午5:53
**/
public class Server {
public static void main(String[] args) throws IOException {
// 开启服务,绑定端口
ServerSocket serverSocket = new ServerSocket(6379);
// 同步阻塞等待消息
Socket socket = serverSocket.accept();
// new一个数组容器
byte[] bytes = new byte[1024];
// 获得输入流
InputStream inputStream = socket.getInputStream();
// 把输入流的数据读到字节数组容器
inputStream.read(bytes);
// 字节数组转成字符串
String msg = new String(bytes);
// 打印
System.out.println(msg);
// 关闭
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端代码:
/**
* 客户端代码
*
* @Author wanglingqiang
* @Date 2020/7/3 下午5:57
**/
public class Client {
public static void main(String[] args) throws IOException {
// 连上Server
Socket socket = new Socket("127.0.0.1", 6379);
// 获得输出流
OutputStream outputStream = socket.getOutputStream();
// 消息
String msg = "Hello world.";
// 向输出流写字节数据
outputStream.write(msg.getBytes());
// 关闭
outputStream.close();
socket.close();
}
}
运行服务端代码,然后运行客户端代码。服务端控制台输出:
Hello world.
升级示例:伪异步
示例一中accept()接收到客户端请求后,后面的读写的操作是同步进行的,在下面的示例中我们对此做升级,用一个线程池处理读写任务。
服务端代码:
/**
* TODO
*
* @author wanglingqiang
* @date 2020/12/9 下午2:57
*/
public class Server {
private static ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(6379));
System.out.println("Server started.");
try {
while (true) {
threadPool.execute(new ServerTask(serverSocket.accept()));
}
} finally {
serverSocket.close();
}
}
private static class ServerTask implements Runnable {
private Socket socket;
public ServerTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream())) {
String msg = inputStream.readUTF();
System.out.println("服务端收到:" + msg);
outputStream.writeUTF("success");
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
客户端代码:
/**
* TODO
*
* @author wanglingqiang
* @date 2020/12/9 下午3:01
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
ObjectOutputStream outputStream = null;
ObjectInputStream inputStream = null;
try {
socket = new Socket();
InetSocketAddress endpoint = new InetSocketAddress("127.0.0.1", 6379);
socket.connect(endpoint);
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
outputStream.writeUTF("Hello world.");
outputStream.flush();
String response = inputStream.readUTF();
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) socket.close();
if (outputStream != null) outputStream.close();
if (inputStream != null) inputStream.close();
}
}
升级示例,做到了对每个客户端开启一个线程做连接后的读写操作,实现伪异步的BIO。但始终还是BIO,accept()、write()、read()方法还是同步的,想做到真正的异步要用NIO。
本文详细介绍Java中ServerSocket和Socket的基本使用,从简单的客户端-服务端通信示例出发,逐步升级到伪异步处理模式,利用线程池提高并发处理能力。通过具体代码实例,展示了如何接收和发送字符串消息,以及如何在服务端处理多个客户端连接。
370

被折叠的 条评论
为什么被折叠?



