Reputation: 2987
I am having a field day trying to figure out why my Java code is not working.
I am supposed to receive the following messages from a C program via sockets.
1~message~i love you\r\n
2~message~do you love me?\r\n 3~message~when are we going to meet again?\r\n 4~message~How about now?\r\n 5~message~Oh! I'm pregnant!\r\n
Instead, I am receiving the following messages instead.
1~message~i love you\r\n 2~message~do you love me?\r\n 2~message~do you love me?\r\n 5~message~Oh! I'm pregnant!\r\n
I ran a port redirector on my laptop and found out that the C program is transmitting the messages correctly. It's my Java program that is not receiving them properly.
I am using Java NIO Channels to receive the messages.
My code as follows:
StringBuffer stringBuffer = new StringBuffer();
int pos = 0; // position of Buffer
// initialize server and client sockets
ServerSocketChannel serverChannel = null;
SocketChannel clientChannel = null;
// initialize ByteBuffer
ByteBuffer inBuffer = ByteBuffer.allocateDirect(65536);
inBuffer.order(ByteOrder.LITTLE_ENDIAN);
try {
serverChannel = ServerSocketChannel.open();
SocketAddress port = new InetSocketAddress(8080);
serverChannel.socket().bind(port);
while (true) {
clientChannel = serverChannel.accept();
while ((bytesRead = clientChannel.read(inBuffer)) != -1) {
inBuffer.flip();
while (inBuffer.get(pos) != '\r') {
stringBuffer.append((char) inBuffer.get(pos));
pos++;
} // end while loop checking for bytesRead
//increment over \r and \n
inBuffer.get();
bytesRead--;
inBuffer.get();
bytesRead--;
pos = pos + 2;
System.out.println(stringBuffer);
stringBuffer.setLength(0);
pos = 0;
} // close while reading bytesRead loop
} // close while(true) loop
} catch (IOException ex) {
}
Upvotes: 0
Views: 1578
Reputation: 533870
I suggest you try plain IO which is simpler for this use case.
ServerSocket serverSocket = new ServerSocket(8080);
while(!serverSocket.isClosed()) {
Socket socket = serverSocket.accept();
System.out.println("Accepted socket "+socket);
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
StringBuilder sb = new StringBuilder();
int b;
while((b = bis.read())>=0) {
if (b == '\r')
b = bis.read();
if (b == '\n') {
System.out.println(sb);
sb.setLength(0);
} else {
sb.append((char) b);
}
}
System.out.println("Closing socket.");
socket.close();
}
Upvotes: 1
Reputation: 1503529
Do you have to use NIO for this? It's generally a lot harder to get right (at least for me). My guess is that the problem is that you're always reading, but you're calling flip
exactly once per read... whereas I'd expect to see two flips, or possibly a flip before the read
and then a clear
at the end of the processing.
Note that you're also completely ignoring bytesRead
- why bother decrementing a variable which you're then reassigning without reading?
Furthermore, you're assuming you get exactly one \r
from each read
call. What if you receive two lines in one call, or one imcomplete line?
I'm not qualified to give the correct NIO code, but I'd recommend that you try to get it working with a plain InputStream
first and then move onto NIO.
Upvotes: 1
Reputation: 91320
read
you're only handling up to the first \r and then continuing by reading again. You may miss the final lines this way.Upvotes: 0