我使用构建了TCP网关。我的服务器能够处理来自客户端的请求并发送响应。但是客户给了SocketException
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)
at java.io.InputStreamReader.read(InputStreamReader.java:151)在客户端读取所有数据之前,服务器似乎正在关闭连接。因此,我想使用so-linger。
setSoLinger应该使服务器套接字保持打开状态,以便在逗留时间内使用。setSoLinger的javadoc表示使用指定的逗留时间(以秒为单位)启用/禁用SO_LINGER。
请参阅https://docs.oracle.com/javase/6/docs/api/java/net/Socket.html#setSoLinger%28boolean,%20int%29
有关设置弹簧集成文档,请参见SoLinger。
我的春天context.xml:
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="${availableServerSocket}"
single-use="true"
so-timeout="10000"
using-nio="false"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"
so-linger="2000"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.ip.tcp.serializer.ByteArrayStxEtxSerializer"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="serverBytes2StringChannel"
error-channel="errorChannel"
reply-timeout="10000"/> <!-- reply-timeout works on inbound-gateway -->
<int:channel id="toSA" />
<int:service-activator input-channel="toSA"
ref="myService"
method="prepare"/>
<int:object-to-string-transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"/>
<int:transformer id="errorHandler"
input-channel="errorChannel"
expression="payload.failedMessage.payload + ':' + payload.cause.message"/>我不确定Spring集成是以秒为单位,还是以毫秒为单位。是否有任何其他标志要设置,以使服务器套接字保持打开直到客户端读取数据。
我看到套接字连接关闭事件几乎立即从服务bean发送响应。服务器似乎没有等待。请帮助设置这样的逗留时间或建议的替代方案。谢谢。
这是日志:
2016-06-01 15:43:46,276 MyService response: ACCEPT:E211001:
2016-06-01 15:43:46.293 DEBUG [pool-1-thread-2][org.springframework.context.support.GenericXmlApplicationContext] Publishing event in org.springframework.context.support.GenericXmlApplicationContext@7a187814: TcpConnectionCloseEvent [source=org.springframework.integration.ip.tcp.connection.TcpNetConnection@4c4b11e9], [factory=crLfServer, connectionId=22.220.220.222:1034:5678:77483643-2156-427f-96dd-a513670a75a3] **CLOSED**
2016-06-01 15:43:46.294 DEBUG [pool-1-thread-2][org.springframework.context.support.GenericXmlApplicationContext] Publishing event in org.springframework.context.support.GenericXmlApplicationContext@7a187814: TcpConnectionExceptionEvent [source=org.springframework.integration.ip.tcp.connection.TcpNetConnection@4c4b11e9, cause=java.net.SocketException: Socket is closed], [factory=crLfServer, connectionId=22.220.220.222:1034:5678:77483643-2156-427f-96dd-a513670a75a3]发布于 2016-06-01 21:34:16
Spring集成不对值执行转换,因此它是秒。
您描述的行为听起来像是so-linger为0(立即发送给close())。
为此,您真的不需要这样逗留;当它没有设置时,TCP堆栈应该优雅地关闭套接字。
您可能需要运行一个网络监视器来了解发生了什么。
如果您信任客户端关闭套接字,则可以删除
single-use="true"
或者将其设置为false,以便服务器在发送回复后不会关闭套接字。
https://stackoverflow.com/questions/37577969
复制相似问题