stx/etx序列化程序

8iwquhpp  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(310)

我正在开发一个使用套接字与服务器通信的应用程序。
我在客户端和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();
   } 
}
polhcujo

polhcujo1#

问题是 reader.readLine() 因为读者搜索 \n 以确定行的末尾。
我使用stx/etx指示消息的开始和结束,然后我应该自己解析它。

private String read() throws IOException {
           int bite = reader.read();
           if (bite!= ByteArrayStxEtxSerializer.STX){
              throw new RuntimeException();
           }
           char[] result = new result[socket.getReceiveBufferSize()]
           while((bite=reader.read())!= ByteArrayStxEtxSerializer.ETX){
                 //-- Collect the bytes and do related stuff
                 result.....
           }

           return new String(result);
        }

相关问题