2013-10-31 84 views
1

服務器使用java,並通過TCP與C++客戶端進行通信。當用戶離開計算機超過5分鐘時,客戶端將發送一個字節數組到服務器。java服務器由spring-integration-ip編寫。如果我應該設置-nio =「true」,我會感到困惑嗎?是否有任何問題關於併發性?如何使用自定義協議來轉換字節數組?我是TCP和spring-integration的新手,感謝您的幫助!使用spring-integration-ip的Java服務器

我hava遇到問題,當我寫我的應用程序遵循示例。服務器反序列化字節流,然後回顯服務,但客戶端無法接收echo服務返回後的序列化的字節流。

彈簧tcp.xml:

<int-ip:tcp-connection-factory 
    id="serverConnectionFactory" 
    type="server" port="5678" 
    using-nio="true" 
    serializer="connectionSerializeDeserialize" 
    deserializer="connectionSerializeDeserialize" /> 

<bean id="connectionSerializeDeserialize" 
     class="com.snail.tcp.CustomSerializerDeserializer" /> 

<int-ip:tcp-inbound-gateway id="gatewayCrLf" 
    connection-factory="serverConnectionFactory" request-channel="toSA" 
    error-channel="errorChannel" /> 

<int:channel id="toSA" /> 

<int:service-activator input-channel="toSA" 
    ref="echoService" method="test" /> 
<bean id="echoService" class="com.snail.tcp.EchoService" /> 

(DE)serialize方法:

private static final int LENGTH = 2; 
private static final int FLAG = 2; 


@Override 
public String deserialize(InputStream is) throws IOException { 
    logger.debug("begin deserialize"); 
    int length = Integer.valueOf(parseString(is, LENGTH)); 
    int flag = Integer.valueOf(parseString(is, FLAG)); 
    String content = parseString(is, length); 
    return content; 
} 

@Override 
public void serialize(String s, OutputStream os) throws IOException { 
    logger.debug("begin serialize:" + s); 
    byte[] content = s.getBytes(); 
    os.write(content); 
    os.flush(); 
} 

回聲服務:

public String test(String input) { 
    logger.debug("echo service:" + input); 
    //some service... 
    return "echo:" + input; 
} 

主要方法:

public static void main(String[] args) { 
    Socket socket = null; 
    Writer out = null; 
    BufferedReader in=null; 
    try { 
     socket = new Socket("127.0.0.1", 5678); 
     socket.setSoTimeout(10000); 
     out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
     out.write("1001HELLOWORLD"); 
     out.flush(); 

     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     StringBuffer str = new StringBuffer(); 
     int c; 
     while ((c = in.read()) != -1) { 
      str.append((char) c); 
     } 
     System.out.println(str.toString()); 
    } catch (UnknownHostException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     try { 
      out.close(); 
      in.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

控制檯日誌:

[DEBUG] com.snail.tcp.CustomSerializerDeserializer-反序列化():開始反序列化

[DEBUG] com.snail.tcp.EchoService測試():回聲服務:HELLOWORLD

[DEBUG] com.snail.tcp.CustomSerializerDeserializer序列化():開始連載:回聲:HELLOWORLD

但是客戶端無法接收反序列化消息 'HELLOWORLD',而不是一個SocketTimeoutException:讀超時... 我想知道我做錯了什麼,thx很多

+0

你在這裏問很多不同的問題,而不是提供很多細節。我建議你把它分解成單獨的問題,並在每個問題中提供一些關於你迄今爲止嘗試過的內容,你想要做什麼以及什麼是錯誤的細節。 – SimonC

回答

3

該框架負責併發處理;如果你支持大量的客戶,你通常只需要NIO;對於少數客戶來說,通常不需要NIO。

您可以使用自定義(de)序列化器,也可以將變壓器放置在入站端點的下游。

我建議您閱讀Documentation,看看samples,如果您還有其他問題,請回復更具體的問題。

+0

感謝您的建議。請您找出上述問題。 –

+0

可能意味着序列化程序不會以客戶期望的方式終止消息;你看到一個'logger.debug(「Message sent」+ message);'log ?.它應該出現在你的序列化器DEBUG消息之後。您的入站郵件具有結構,但您的出站只發送原始數據。客戶不希望有某種結構嗎?您可能需要運行Wireshark或類似的工具來查看發送的內容。 –

+0

我調試我的服務器。當它在serialize()方法中執行os.write(content)時,它引發java.nio.channels.ClosedChannelException.I只想返回一個簡單的字符串,如「SUCCESS」給客戶端,而不是一個結構。我可以在serialize()方法或其他地方認識到這一點嗎? –