基于Socket实现客户端与服务端通讯
socket 概述
Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何
在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协
议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信
息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议
端口。
Socket整体流程
Socket编程主要涉及到客户端和服务端两个方面,首先是在服务器端创建一个服务器套接字
package com.moon.server;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @ClassName Server
* @Author zhangqing
* @Date 2022/8/15
* @Description 服务端
* @Version 1.0
*/
@Slf4j
public class Server {
//1.创建一个线程池,如果有客户端连接就创建一个线程, 与之通信
ExecutorService executorService = Executors.newCachedThreadPool();
//2.创建 ServerSocket 对象
public Server() {
init(9999);
}
private void init(int port) {
//2.创建 ServerSocket 对象
try {
ServerSocket serverSocket = new ServerSocket(port);
log.info("服务端已经启动");
while (true) {
//3.监听客户端
Socket socket = serverSocket.accept();
log.info("有客户端连接使用线程池进行处理");
this.executorService.execute(() -> {
handle(socket);
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 异步处理请求
*
* @param socket
*/
private void handle(Socket socket) {
log.info("当前处理的线程为:{},线程名称为{}", Thread.currentThread().getId(), Thread.currentThread().getName());
//从连接中获取请求
try {
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int read = inputStream.read(bytes);
log.info("客户端信息为:{}",new String(bytes,0,read));
//获取输出流写回客户端
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
outputStream.write(line.getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Server server = new Server();
}
}
package com.moon.client;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
/**
* @ClassName Client
* @Author zhangqing
* @Date 2022/8/15
* @Description 客户端
* @Version 1.0
*/
@Slf4j
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1",9999);
OutputStream outputStream = socket.getOutputStream();
log.info("请输入发给服务器的信息:");
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
outputStream.write(s.getBytes());
InputStream inputStream = socket.getInputStream();
byte[]bytes = new byte[1024];
int read = inputStream.read(bytes);
log.info("服务端回复:{}",new String(bytes,0,read));
socket.close();
}
}
运行测试如下:首先启动服务端代码,服务端已经启动,在启动客户端,向服务端发送消息:
//service info
15:25:54.415 [main] INFO com.moon.server.Server - 服务端已经启动
15:26:02.214 [main] INFO com.moon.server.Server - 有客户端连接使用线程池进行处理
15:26:02.247 [pool-1-thread-1] INFO com.moon.server.Server - 当前处理的线程为:12,线程名称为pool-1-thread-1
15:26:20.156 [pool-1-thread-1] INFO com.moon.server.Server - 客户端信息为:你好 我是 客户端
你好 我是服务器
15:28:37.137 [main] INFO com.moon.server.Server - 有客户端连接使用线程池进行处理
15:28:37.137 [pool-1-thread-2] INFO com.moon.server.Server - 当前处理的线程为:13,线程名称为pool-1-thread-2
15:28:45.347 [pool-1-thread-2] INFO com.moon.server.Server - 客户端信息为:我是moon
你好moon
//client1 info
15:28:37.138 [main] INFO com.moon.client.Client - 请输入发给服务器的信息:
你好 我是 客户端
15:28:52.819 [main] INFO com.moon.client.Client - 服务端回复:你好 我是服务器
//client2 info
15:28:37.138 [main] INFO com.moon.client.Client - 请输入发给服务器的信息:
我是moon
15:28:52.819 [main] INFO com.moon.client.Client - 服务端回复:你好moon