while(true)
{
sel.select();
Set readyKeys = sel.selectedKeys();
Iterator itr = readyKeys.iterator();
while(itr.hasNext())
{
SelectionKey key = (SelectionKey) itr.next();
itr.remove();
if(key.isReadable())
{
inputbuf.clear();
sc.read(inputbuf);
inputbuf.flip();
byte cmd = inputbuf.get();
outputbuf.clear();
//do something
}
}
}
[java] SocketChannel selector doesn't block
I'm having a problem with a game server I'm writing. I'm using a Selector, but when the client sends two packets quickly, it will be received as one key with one packet stuck on the end of the other. What's wrong?
This is a feature, not a bug. Both of the packets were written to the byte buffer before you read from it. You'll need to modify your code so that it's guaranteed to read only one packet at a time, regardless of how many are in the byte buffer.
Quote:Original post by RobAU78
This is a feature, not a bug. Both of the packets were written to the byte buffer before you read from it. You'll need to modify your code so that it's guaranteed to read only one packet at a time, regardless of how many are in the byte buffer.
So would that mean iterating through all the bytes in the buffer and figuring out where a new packet starts, or is there a better way?
(Assuming you're using TCP)
TCP is a stream protocol. This means it does not guarantee the preservation of 'boundaries' implicit when you attempt to send a given buffer at a time.
You need to have a framing protocol layered over the top of it. A simple solution is to prefix each packet of data with the packet length. You can then use this on the receiver's end to determine where packets should be delimited and split apart from the incoming TCP stream.
See Question 14 in the Multiplayer and Network Programming forum FAQ.
TCP is a stream protocol. This means it does not guarantee the preservation of 'boundaries' implicit when you attempt to send a given buffer at a time.
You need to have a framing protocol layered over the top of it. A simple solution is to prefix each packet of data with the packet length. You can then use this on the receiver's end to determine where packets should be delimited and split apart from the incoming TCP stream.
See Question 14 in the Multiplayer and Network Programming forum FAQ.
Thanks for that, I never thought of TCP as being a stream protocol. This is actually a custom server for another game, so I can't edit the packets, but I'm guessing something like this should work, since each type of packet has a fixed length:
itr.remove();
if(key.isReadable())
{
inputbuf.clear();
sc.read(inputbuf);
inputbuf.flip();
while(inputbuf.remaining() > 0)
{
byte cmd = inputbuf.get();
//do some more get() calls based on what type of packet it is
}
}
(untested, I can't get to my code from here)
This is a bit offtopic, but I have another question. When 2 clients from the same IP are connected, is it possible that data meant for one might be sent to the other?
I've been testing with 2 clients and server on the same machine, and I noticed that about 50% of the time the 2nd client connects, it will not be spawned on the 1st client's screen, instead the 1st client will respawn itself back at the spawn point.
I've debugged a lot and the only thing I can think of is that the 1st client is receiving a spawn packet meant for the other. Is this possible?
itr.remove();
if(key.isReadable())
{
inputbuf.clear();
sc.read(inputbuf);
inputbuf.flip();
while(inputbuf.remaining() > 0)
{
byte cmd = inputbuf.get();
//do some more get() calls based on what type of packet it is
}
}
(untested, I can't get to my code from here)
This is a bit offtopic, but I have another question. When 2 clients from the same IP are connected, is it possible that data meant for one might be sent to the other?
I've been testing with 2 clients and server on the same machine, and I noticed that about 50% of the time the 2nd client connects, it will not be spawned on the 1st client's screen, instead the 1st client will respawn itself back at the spawn point.
I've debugged a lot and the only thing I can think of is that the 1st client is receiving a spawn packet meant for the other. Is this possible?
Quote:Original post by Jacob_
Thanks for that, I never thought of TCP as being a stream protocol. This is actually a custom server for another game, so I can't edit the packets, but I'm guessing something like this should work, since each type of packet has a fixed length:
itr.remove();
if(key.isReadable())
{
inputbuf.clear();
sc.read(inputbuf);
inputbuf.flip();
while(inputbuf.remaining() > 0)
{
byte cmd = inputbuf.get();
//do some more get() calls based on what type of packet it is
}
}
(untested, I can't get to my code from here)
Sure, that's about the only way to do it in this case.
Quote:This is a bit offtopic, but I have another question. When 2 clients from the same IP are connected, is it possible that data meant for one might be sent to the other?
I've been testing with 2 clients and server on the same machine, and I noticed that about 50% of the time the 2nd client connects, it will not be spawned on the 1st client's screen, instead the 1st client will respawn itself back at the spawn point.
I've debugged a lot and the only thing I can think of is that the 1st client is receiving a spawn packet meant for the other. Is this possible?
On the network stack side, no. Each TCP connection from a single machine will have a different port on the client side, allowing data to be routed to the correct application instance. Sounds like you're getting something mixed up in your application side, whether it be the network code, or perhaps something more game-specific related to spawning or something.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement