Valhalla Legends Forums Archive | Java Programming | question on java.nio.channels.* package

AuthorMessageTime
Ender
import iago.*
;D

Well, as for my situation, I only need to have one socket, but I want it to be non-blocking in a single thread, instead of blocking in multiple threads. I'm using the java.nio.channels package to do this. It doesn't make sense to have a Selector with SelectionKeys since I only have one socket. Yet when I use the SocketChannel.write(myByteBuffer) and SocketChannel.read(myByteBuffer) methods they don't send/receive at all whatsoever! And this is in blocking mode as well as non-blocking. What am I doing wrong here?

I'll post some code as an example:
[code]
public class TestClient
{
public static void main(String[] args) throws IOException
{
/* Create blocking channel */
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(true);
channel.connect(new InetSocketAddress("localhost", 5604));
/* Finish connecting */
while (channel.finishConnect())
;
/* Add data to a packet and send it */
ByteBuffer bbout = ByteBuffer.allocate(7);
bbout.put((byte) 0x0F);
bbout.put((byte) 0x01);
bbout.put((byte) 0x07);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
channel.write(bbout);
/* Read data */
ByteBuffer bbin = ByteBuffer.allocate(4);
channel.read(bbin);
/* Print out a summary of the data */
System.out.println(bbin.toString());
}
}
[/code]

This client does nothing... When I make clients using the regular Socket, InputStream, and OutputStream objects it works. My server is fine, that's my point. It's the client... the above code...

By the way, I set it blocking just so that it is guaranteed to perform the above io operations. The problem is not that it's blocking/nonblocking - it's that I just can't get the SocketChannel class to read/write. I want it to be non-blocking though, which is why I'm using the SocketChannel class to begin with.

So does anyone see why the above code isn't sending or receiving anything? What I'm doing wrong with the java.nio.channels.SocketChannel class?

EDIT: iago, I looked at your SocketManager class, and it was helpful, but I don't want to have a Selector with keys because I only need one socket.
January 16, 2006, 2:51 AM
iago
Ah, awesome mistake, it took me awhile to track down. 

First, let me just say, I *hate* ByteBuffer.  Just thought I should be clear on that. 

Next, here's a part of your code, with a different address:
[quote]        channel.connect(new InetSocketAddress("www.google.ca", 80));
        /* Finish connecting */
        System.out.println("Finishing connect");
        while (channel.finishConnect())
            ;
        System.out.println("Finished connect");
        /* Add data to a packet and send it */
[/quote]

And here's the output:
[quote]iago@slayer:~/tmp$ java TestClient
Finishing connect
[/quote]

And it stops there.  Apparently, it's getting itself into an infinite loop. 

That should be enough for you to figure out what's going wrong.  :)


By the way, if you need an answer from me I recommend posting at www.x86labs.org, in addition to here.  I check that board more often. However, if you post there, you wont get Kp's witty yet helpful responses :)
January 16, 2006, 3:34 AM
Ender
Oh yea, I'm saying while(true) do nothing. Hehe, thanks iago. I may have more questions though! ;P
January 16, 2006, 3:44 AM
Ender
Hmm... it still doesn't work when I change it to while (!channel.finishConnect()) ; It's not writing/receiving.
January 16, 2006, 3:50 AM
iago
Hmm, I used a packetsniffer and this code:

[code]import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;

public class TestClient
{
    public static void main(String[] args) throws IOException
    {
        /* Create blocking channel */
        SocketChannel channel = SocketChannel.open();
        //channel.configureBlocking(true);
        channel.connect(new InetSocketAddress("www.google.ca", 80));
        /* Finish connecting */
        System.out.println("Finishing connect");
        while (channel.finishConnect())
            ;
        System.out.println("Finished connect");
        /* Add data to a packet and send it */
        ByteBuffer bbout = ByteBuffer.allocate(1000);
        bbout.put("GET / HTTP/1.0\r\n\r\n".getBytes());

        System.out.println("Sending output");
        channel.write(bbout);
        /* Read data */
        ByteBuffer bbin = ByteBuffer.allocate(100);

        System.out.println("Reading input");
        channel.read(bbin);
        /* Print out a summary of the data */
        System.out.println(bbin.toString());
    }
}
[/code]

And it successfully sent.  It didn't send the right data, but I don't care. :)
January 16, 2006, 4:07 AM
Ender
[quote author=iago link=topic=13927.msg141998#msg141998 date=1137384423]
And it successfully sent. It didn't send the right data, but I don't care. :)
[/quote]

Hm, I don't understand. It's not an endian problem, is it? I tried using the ByteBuffer.order(ByteOrder o) method for both big and little endian, didn't change anything. How is the data being sent not the right data?
January 16, 2006, 4:23 AM
iago
Run my test program and packetsniff, it's sending totally wrong data.  I forget how I solved that problem, but that's a chapter of my programming career that I never want to return to, once I linked it up with my packet buffer class, I never looked back. 

Load up Ethereal, that would be much more beneficial to you. 
January 16, 2006, 5:28 AM
Ender
Yeah, I see what you mean. I used Ethereal and ran that program, and here is the traffic between me and google:

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 30 e9 ab 40 00 80 06  3c 9c c0 a8 00 66 48 0e  .0..@... <....fH.
0020  cb 63 07 fa 00 50 9a 55  bd 7b 00 00 00 00 70 02  .c...P.U .{....p.
0030  40 00 0e 84 00 00 02 04  05 b4 01 01 04 02        @....... ...... 
[/code]

google > me
[code]
0000  00 12 3f 1c 6d c8 00 11  95 74 b2 0e 08 00 45 20  ..?.m... .t....E
0010  00 2c 1c 23 00 00 ea 06  e0 08 48 0e cb 63 c0 a8  .,.#.... ..H..c..
0020  00 66 00 50 07 fa 67 b1  b7 ea 9a 55 bd 7c 60 12  .f.P..g. ...U.|`.
0030  1f fe 23 e0 00 00 02 04  05 b4 00 00 91 8a 2b bf  ..#..... ......+.
[/code]

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 28 e9 ac 40 00 80 06  3c a3 c0 a8 00 66 48 0e  .(..@... <....fH.
0020  cb 63 07 fa 00 50 9a 55  bd 7c 67 b1 b7 eb 50 10  .c...P.U .|g...P.
0030  44 70 17 2b 00 00                                  Dp.+..         
[/code]

WTF?
(there's more, but i won't bother)
January 16, 2006, 11:21 PM
iago
Are you showing us the data section, or the IP/TCP headers?

The important part (in fact, the only part that matters for this) is the "data" section.

Set the display filter to, "tcp.port == 80 && tcp.len > 0", that'll filter out the unimportant stuff. 
January 17, 2006, 1:04 AM
JoeTheOdd
The data section starts at 0x37. The last packet is empty, but the other two have data (8 and 10 bytes, in that order).
January 17, 2006, 1:20 PM
iago
[quote author=Joe link=topic=13927.msg142144#msg142144 date=1137504012]
The data section starts at 0x37.
[/quote]
That isn't necessarely true.  It might be in these packets, but it's possible for certain headers' lengths to vary. 
January 17, 2006, 3:41 PM
Ender
Here's my whole conversation with google, in chronology of first to last:
(I set the display filter to "tcp.port == 80 && tcp.len > 0" as iago said but I also set capture filter to host www.google.com so I hope the capture filter doesn't override it...). Well anyways now that I check the packets I think that the one that has a shitload of nulls is the only one with data because it's the only one that Ethereal says has http data in it. So... just look at that one (with the shitload of nulls). I'm posting the others in case I'm wrong. So... what's up with all the nulls?  --; And why isn't the ByteBuffer class working =[

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 28 14 71 40 00 80 06  11 df c0 a8 00 66 48 0e  .(.q@... .....fH.
0020  cb 63 0a 3f 00 50 74 46  41 83 b1 4a a5 03 50 14  .c.?.PtF A..J..P.
0030  00 00 c4 a9 00 00                                  ......         
[/code]

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 30 14 76 40 00 80 06  11 d2 c0 a8 00 66 48 0e  .0.v@... .....fH.
0020  cb 63 0a 43 00 50 af 3a  ef 37 00 00 00 00 70 02  .c.C.P.: .7....p.
0030  40 00 c5 99 00 00 02 04  05 b4 01 01 04 02        @....... ...... 

[/code]

google > me
[code]
0000  00 12 3f 1c 6d c8 00 11  95 74 b2 0e 08 00 45 20  ..?.m... .t....E
0010  00 2c f5 fa 00 00 ea 06  06 31 48 0e cb 63 c0 a8  .,...... .1H..c..
0020  00 66 00 50 0a 43 29 b7  44 06 af 3a ef 38 60 12  .f.P.C). D..:.8`.
0030  1f fe 8c d4 00 00 02 04  05 b4 00 00 be ca 31 95  ........ ......1.
[/code]

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 28 14 77 40 00 80 06  11 d9 c0 a8 00 66 48 0e  .(.w@... .....fH.
0020  cb 63 0a 43 00 50 af 3a  ef 38 29 b7 44 07 50 10  .c.C.P.: .8).D.P.
0030  44 70 80 1f 00 00                                  Dp....         
[/code]

me > google (holy shit that's a lot of nulls)
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  03 fe 14 78 40 00 80 06  0e 02 c0 a8 00 66 48 0e  ...x@... .....fH.
0020  cb 63 0a 43 00 50 af 3a  ef 38 29 b7 44 07 50 18  .c.C.P.: .8).D.P.
0030  44 70 7c 41 00 00 00 00  00 00 00 00 00 00 00 00  Dp|A.... ........
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0090  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
00f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0100  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0110  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0150  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0170  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0180  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0190  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
01f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0220  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0230  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0240  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0250  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0270  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0290  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
02f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0300  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0310  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0320  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0330  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0340  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0350  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0360  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0370  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0380  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0390  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
03f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........
0400  00 00 00 00 00 00 00 00  00 00 00 00              ........ ....   
[/code]

google > me
[code]
0000  00 12 3f 1c 6d c8 00 11  95 74 b2 0e 08 00 45 20  ..?.m... .t....E
0010  00 28 bd 01 00 00 ea 06  3f 2e 48 0e cb 63 c0 a8  .(...... ?.H..c..
0020  00 66 00 50 0a 43 29 b7  44 07 af 3a f3 0e 50 10  .f.P.C). D..:..P.
0030  1f fe a0 bb 00 00 00 00  00 00 00 00 f8 5e 0f e6  ........ .....^..
[/code]

google > me
[code]
0000  00 12 3f 1c 6d c8 00 11  95 74 b2 0e 08 00 45 20  ..?.m... .t....E
0010  00 28 49 f7 00 00 ea 06  b2 38 48 0e cb 63 c0 a8  .(I..... .8H..c..
0020  00 66 00 50 0a 43 29 b7  44 07 af 3a f3 0e 50 11  .f.P.C). D..:..P.
0030  1f fe a0 ba 00 00 00 00  00 00 00 00 1f 57 25 ab  ........ .....W%.
[/code]

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 28 16 2f 40 00 80 06  10 21 c0 a8 00 66 48 0e  .(./@... .!...fH.
0020  cb 63 0a 43 00 50 af 3a  f3 0e 29 b7 44 08 50 10  .c.C.P.: ..).D.P.
0030  44 70 7c 48 00 00                                  Dp|H..         
[/code]

me > google
[code]
0000  00 11 95 74 b2 0e 00 12  3f 1c 6d c8 08 00 45 00  ...t.... ?.m...E.
0010  00 28 16 30 40 00 80 06  10 20 c0 a8 00 66 48 0e  .(.0@... . ...fH.
0020  cb 63 0a 43 00 50 af 3a  f3 0e 29 b7 44 08 50 14  .c.C.P.: ..).D.P.
0030  00 00 c0 b4 00 00                                  ......         
[/code]

January 17, 2006, 11:50 PM
iago
Good, now post it again with ONLY the data section. 
January 18, 2006, 12:02 AM
Ender
Ah, the reason it wasn't working is because the ByteBuffer needs to be flipped before being sent. This sort of trims the buffer, setting the limit at the current position.

[code]
/* Add data to a packet and send it */
ByteBuffer bbout = ByteBuffer.allocate(7);
bbout.put((byte) 0x0F);
bbout.put((byte) 0x01);
bbout.put((byte) 0x07);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
bbout.put((byte) 0x01);
bbout.flip(); // FLIP THE BUFFER
channel.write(bbout);
[/code]
January 21, 2006, 2:19 AM

Search