gpt4 book ai didi

java - 如何保持 TCP 套接字打开?

转载 作者:可可西里 更新时间:2023-11-01 02:33:03 25 4
gpt4 key购买 nike

我们的应用程序与许多服务器进行类似乒乓球的对话(每个服务器都有一个相应的线程,用于建立这些连接)。下面的代码有效,但它会为每个新请求打开一个新连接,并且只使用一次,这很快就会达到服务器设置的最大连接上限。

数据提供者.java

public static ZnResult sendTcpQuery(String xml, String url, int port) {
List<ZnXmlResult> results = new ArrayList<>();
String xmlString = xml != null ? new String((xml + "\n").getBytes()) : "";
int error = ZnResult.OK;
try (Socket clientSocket = new Socket(url, port)) {
clientSocket.setSoTimeout(CONNECTION_TIMEOUT);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
try (BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "UTF-8"))) {
outToServer.writeBytes(xmlString);
try (StringWriter responseFromServer = new StringWriter()) {
String readLine;
while ((readLine = inFromServer.readLine()) != null) {
...
}
}
outToServer.close();
clientSocket.close();
}
} catch (Exception ex) {
LOG.error("Exception {}", url + ":" + port, ex);
error = ZnResult.ERR;
}
return error == ZnResult.OK ? new ZnResult(results) : new ZnResult(error);
}

我怎样才能改造它,使一切都可以在一个连接中完成?我想我会做这样的事情:

SocketFactory.java

public class SocketFactory {
private static HashMap<String, Socket> socketsByAddress = new HashMap<>();
private static HashMap<Socket, DataOutputStream> outputStreamsBySocket = new HashMap<>();
private static HashMap<Socket, BufferedReader> readersBySocket = new HashMap<>();

public static Socket getSocket(String address) {
String ip = Tools.getIpFromAddress(address);
int port = Tools.getPortFromAddress(address);
Socket socket = socketsByAddress.get(address);
if (socket == null) {
try {
socket = new Socket(ip, port);
socket.setSoTimeout(60000);
socketsByAddress.put(address, socket);
} catch (IOException ex) {
Logger.getLogger(SocketFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
return socket;
}

public static DataOutputStream getOutputStream(Socket socket) {
DataOutputStream outputStream = outputStreamsBySocket.get(socket);
if (outputStream == null) {
try {
outputStream = new DataOutputStream(socket.getOutputStream());
outputStreamsBySocket.put(socket, outputStream);
} catch (IOException ex) {
Logger.getLogger(SocketFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
return outputStream;
}

public static BufferedReader getReader(Socket socket) {
BufferedReader reader = readersBySocket.get(socket);
if (reader == null) {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
readersBySocket.put(socket, reader);
} catch (IOException ex) {
Logger.getLogger(SocketFactory.class.getName()).log(Level.SEVERE, null, ex);
}
}
return reader;
}
}

数据提供者.java

public static ZnResult sendTcpQuery(String xml, String url, int port) {
List<ZnXmlResult> results = new ArrayList<>();
int error = ZnResult.OK;
try {
String xmlString = xml != null ? new String((xml + "\n").getBytes()) : "";
Socket clientSocket = SocketFactory.getSocket(url + ":" + port);
DataOutputStream outToServer = SocketFactory.getOutputStream(clientSocket);
BufferedReader inFromServer = SocketFactory.getReader(clientSocket);
outToServer.writeBytes(xmlString);
try (StringWriter responseFromServer = new StringWriter()) {
String readLine;
while ((readLine = inFromServer.readLine()) != null) {
...
}
}
} catch (Exception ex) {
LOG.error("Exception {}", url + ":" + port, ex);
error = ZnResult.ERR;
}
return error == ZnResult.OK ? new ZnResult(results) : new ZnResult(error);
}

但它不起作用,只有第一个通过。

最佳答案

此循环读取直到流结束。

while ((readLine = inFromServer.readLine()) != null) {

一个流只结束一次。也就是说,您不能结束流,但稍后会再次使用它。

你需要做什么;

  • 有一个不能出现在你的数据中的终止行。例如等待 [EOF]"
  • 先发送数据的长度,然后只读取那么多的数据。

关于java - 如何保持 TCP 套接字打开?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52744113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com