Reputation: 3288
We used the below piece of code for a Tcp server:
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
Socket socket = serverSocket.accept();
new ServerThread(socket).start();
}
}
and ServerThread
:
private class ServerThread extends Thread {
private final Socket socket;
private ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (final InputStreamReader reader = new InputStreamReader(socket.getInputStream());
final OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream())) {
int bytesRead;
char[] buffer = new char[1024];
while ((bytesRead = reader.read(buffer)) != -1){
System.out.println(new String(buffer, 0, bytesRead));
writer.write(/* some char[] */);
writer.flush();
}
// ...
socket.close();
} catch (IOException exception){
// ...
socket.close();
}
}
}
We recently switched to using Spring integration:
@Bean
public TcpNetServerConnectionFactory connectionFactory() {
TcpNetServerConnectionFactory factory = new TcpNetServerConnectionFactory(9000);
ByteArrayRawSerializer serializer = new ByteArrayRawSerializer();
factory.setDeserializer(serializer);
factory.setSerializer(serializer);
return factory;
}
@Bean
public TcpReceivingChannelAdapter channelAdapter(AbstractServerConnectionFactory connectionFactory) {
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(connectionFactory);
adapter.setOutputChannel(messageChannel());
return adapter;
}
@Bean
@ServiceActivator(inputChannel = "outputChannel")
public TcpSendingMessageHandler messageHandler(AbstractServerConnectionFactory connectionFactory){
final TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(connectionFactory());
return handler;
}
@Bean
public MessageChannel messageChannel() {
return new DirectChannel();
}
@Bean
@Transformer(inputChannel = "messageChannel", outputChannel = "loggingChannel")
public ObjectToStringTransformer loggingTransformer() {
return new ObjectToStringTransformer();
}
@Bean
@ServiceActivator(inputChannel = "loggingChannel")
public void log(String message) {
System.out.println(message);
}
with above configuration; we successfully receive messages and print them. When I access the Spring application with a Telnet client, I do get the messages on terminal, however, a client application (written with C++ with WinSock2.h
) gets a timeout. What is different with the application and how do I imitate the behaviour of OutputStreamWriter
s
writer.write(/* some char[] */);
writer.flush();
with TcpSendingMessageHandler
for the WinSock2.h
application?
Upvotes: 0
Views: 75
Reputation: 121177
Did you read ByteArrayRawSerializer
JavaDocs? Do you know that it doesn't close a Socket
by itself as you do in your custom code after reading and writing?
you probably need to think about closing a Connection
after using it.
See this option on the ConnectionFactory
:
/**
* If true, sockets created by this factory will be used once.
* @param singleUse The singleUse to set.
*/
public void setSingleUse(boolean singleUse) {
Then TcpSendingMessageHandler
will close it after sending a message into that OutputStreamWriter
.
Upvotes: 0