今天我们分享Java语言 Socket和ServerSocket 实战使用,这也是rpc远程调用的基础底层实现方式之一,通过监听某个或者多个ip、port实时获取客户端发来的数据,简单清晰可见,今天我们实战演示:
1、客户端核心伪代码
public static void main(String[] args) throws Exception{
//Socket socket = new Socket("localhost", 8089);
Socket socket = new Socket("10.18.3.110", 8089);
//代理ip:port (x.x.x.x:8089) 映射访问到真实 ip:port(10.18.3.110:8089)
//Socket socket = new Socket("x.x.x.x", 8089);
System.out.println("Connected to server: " + socket.getInetAddress());
String str = "测试客户端功能";
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
//OutputStream outputStream = socket.getOutputStream();
dataOutputStream.write(str.getBytes());
// dataOutputStream.write(xml.getBytes("UTF-8"));//设置字符集
socket.close();
}
2、服务器核心伪代码:SpringMVC框架的代码
1)、服务启动后就扫描执行的类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.net.ServerSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Component
public class ServerSocketRunCommand implements CommandLineRunner {
private ExecutorService executorService = Executors.newFixedThreadPool(3);
@Autowired
UserService userService;
@Override
public void run(String... args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8089);
while (true){
executorService.execute(new UserServerThread(serverSocket.accept(),userService));
}
}
}
2)、线程类逻辑代码
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
@AllArgsConstructor
@Slf4j
public class UserServerThread extends Thread{
private Socket client;
private UserService userService;
@SneakyThrows
@Override
public void run() {
try {
//客户端的ip和端口号打印
log.info("Client connected:{}:{}",client.getInetAddress(),client.getPort());
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
String message = new String(buffer, 0, bytesRead);
//String message =new String(buffer);
log.info("message :{}",message );
}catch (Exception e){
throw new Exception(e);
}finally {
client.close();
}
}
}
3、启动调用
一般情况下先启动服务端,然后在启动客户端,这样放置数据丢失。
4、还有一写其他的写法和原理
网上有篇博客可以参考一下:网络编程原理
使用详解二:客户端和服务端的组合使用
字节截取定长:java截取字节
5、此种实战方式,一般适合单体服务、成本低、并发量低的业务场景下;如果是服务集群、微服务、三高场景,建议使用标准的服务注册中间件。