我正在开发一个使用套接字与服务器通信的应用程序。
我在客户端和java上使用spring集成 ServerSocket
在服务器端。我使用stx/etx对套接字上的消息进行序列化,以指示消息的开始和结束。为此,我使用spring ByteArrayStxEtxSerializer
班级。
但问题是什么时候 ByteArrayStxEtxSerializer
用作序列化,在服务器端以一定的延迟接收消息,反之亦然,有时从未接收到消息。
唯一让我困惑的是,当我用 ByteArrayCrLfSerializer
,整个过程进展顺利,没有任何延误或失败。
我对客户端和服务器端的代码剪贴如下:
服务器端:
public void startSocketServer(){
try (final ServerSocket serverSocket = new ServerSocket(9992)) {
gl.info("Server is listening on: " + serverSocket.getLocalSocketAddress());
while (true) {
final Socket socket = serverSocket.accept();
gl.info("A new client connected");
new SocketThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class SocketThread extends Thread {
private final Socket socket;
private final PrintWriter writer;
private final BufferedReader reader;
public SocketThread(Socket socket) throws IOException {
this.socket = socket;
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(input));
writer = new PrintWriter(output, true);
}
public void run() {
try {
while (true) {
String inputMessage = reader.readLine();
if (inputMessage != null) {
MessageType messageType = getTypeInstance(inputMessage);
if (messageType instanceof LoginMessage loginMessage) {
if (isAuthenticated(loginMessage.getUsername(), loginMessage.getPassword())) {
gl.info("#### SERVER => User authorized");
final String messageBody = createConnectionAckMessage();
print(writer, messageBody);
} else {
print(writer, createRefusalMessage());
}
} else if (messageType instanceof StartTransferingData startData) {
getMessages().forEach(message-> print(writer, message));
} else if (messageType instanceof DisconnectionAck disAck) {
print(writer, "By then")
break;
}
}
}
socket.close();
} catch (IOException ex) {
gl.info("Server exception: " + ex.getMessage());
}
}
private void print(PrintWriter writer, String msg) {
writer.print(ByteArrayStxEtxSerializer.STX);
writer.print(msg);
writer.print(ByteArrayStxEtxSerializer.ETX);
}
}
以及客户端:
public class CapConfig {
@MessagingGateway(defaultRequestChannel = "toTcp", errorChannel = "errorChannel")
public interface TcpGateway {
@Gateway
void send(String in);
}
@Bean
public MessageChannel toTcp() {
return new DirectChannel();
}
@Bean
public AbstractClientConnectionFactory clientCF() {
return Tcp.netClient("localhost", 9992)
.serializer(TcpCodecs.stxetx())
.deserializer(TcpCodecs.stxetx())
.get();
}
@Bean
public IntegrationFlow tcpOutFlow(AbstractClientConnectionFactory connectionFactory) {
return IntegrationFlows.from(toTcp())
.handle(Tcp.outboundAdapter(connectionFactory))
.get();
}
@Bean
public IntegrationFlow tcpInFlow(AbstractClientConnectionFactory connectionFactory) {
return IntegrationFlows.from(Tcp.inboundAdapter(connectionFactory))
.transform(stringTransformer)
.log()
//---- Do some other stuffs
.get();
}
}
1条答案
按热度按时间polhcujo1#
问题是
reader.readLine()
因为读者搜索\n
以确定行的末尾。我使用stx/etx指示消息的开始和结束,然后我应该自己解析它。