Reputation: 4600
I have simple client and server, the client is based on NIO where as the server is a simple old style program.
I am using the client in its default mode which is blocking. In the program i try to write from the client side, server reads it. Then server replies and the client reads it.
I am able to write into the server with no issues, but the read from the Server in the client is proving to be problematic. As it is in blocking mode, i expect that it never returns 0 according to the documentation. But thats not what is happening, i always see the return from client_channel.read as 0.
*******************************SERVER*******************************************
class MyBlockingServer extends Thread
{
private int M_PortNumber;
private ServerSocket M_ServerSocket;
MyBlockingServer(int PortNumber)
{
M_PortNumber = PortNumber;
try {
M_ServerSocket = new ServerSocket(M_PortNumber);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run()
{
int my_number = 0;
while(true)
{
try {
Socket ClientServerTuple = M_ServerSocket.accept();
//System.out.println("Server address is "+ ClientServerTuple.getLocalAddress() + "Server Port is " + ClientServerTuple.getLocalPort());
//System.out.println("Client address is " + ClientServerTuple.getRemoteSocketAddress() + "Client address is" + ClientServerTuple.getPort());
DataInputStream inputStream = new DataInputStream(ClientServerTuple.getInputStream());
byte b[] = new byte[48];
inputStream.read(b);
System.out.println("[SERVER]" + new String(b));
DataOutputStream outputStream = new DataOutputStream(ClientServerTuple.getOutputStream());
byte c[] = new byte[100];
String output= new String("Thanks for connection, you suck tata" + " "+ my_number);
c = output.getBytes();
outputStream.write(c);
my_number++;
System.out.println("write done");
ClientServerTuple.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
void socket_close()
{
try {
M_ServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class JavaBlocking
{
public static void main(String []args)
{
MyBlockingServer Server = new MyBlockingServer(8000);
try {
Server.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
*******************************CLIENT*******************************************
public class JavaChannels
{
public static void main(String []args)
{
SocketChannel client_channel = null;
try {
client_channel = SocketChannel.open();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("[Async Client] Socket channel open");
try {
client_channel.connect(new InetSocketAddress("127.0.0.1",8000));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("[Async Client] Socket channel connected");
ByteBuffer my_buffer = ByteBuffer.allocate(248);
try {
my_buffer.put("seven77".getBytes("UTF-8"));
} catch (UnsupportedEncodingException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
my_buffer.flip();
try {
int bytes_written = client_channel.write(my_buffer);
while(my_buffer.hasRemaining())
{
bytes_written = client_channel.write(my_buffer);
}
System.out.println("[Async Client] Wrote "+ bytes_written +" bytes");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("[Async Client] Socket channel write finished");
my_buffer.clear();
my_buffer.flip();
try {
int read_length = client_channel.read(my_buffer);
System.out.println("Initial read is " + read_length + " bytes");
while(read_length !=-1)
{
read_length = client_channel.read(my_buffer);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Reading the buffer." +"Read "+read_length +"bytes");
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("[Async Client] server says" + new String(my_buffer.array()));
try {
client_channel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output i am seeing from the client side is as follows
Initial read is 0 bytes
Reading the buffer.Read 0bytes
Reading the buffer.Read 0bytes
Reading the buffer.Read 0bytes
Upvotes: 1
Views: 1720
Reputation: 718698
I think that this is wrong:
System.out.println("[Async Client] Socket channel write finished");
my_buffer.clear();
my_buffer.flip();
The clear
prepares the buffer for reading by setting the position to zero and the limit to the capacity.
But the flip
then sets the limit to the position; i.e. zero. That means than when you attempt to read into the buffer, there is space for zero bytes.
Get rid of that flip
call.
As it is in blocking mode, i expect that it never returns 0 according to the documentation.
Which documentation? The javadocs for SocketChannel.read(ByteBuffer)
says:
"It is guaranteed, however, that if a channel is in blocking mode and there is at least one byte remaining in the buffer then this method will block until at least one byte is read. "
In this case, the highlighted condition is false.
Upvotes: 2