views:

227

answers:

1

I'm having a problem with a multiplayer game. Right now, I'm just trying to get the server to send the current level to the client. The server is definitely sending the data, but it never gets to the client application.

Client code:

    public void run() {
    while(true)
    {
        try {
            sel.select();
            Set readyKeys = sel.selectedKeys();
            Iterator itr = readyKeys.iterator();
            while(itr.hasNext())
            {
                SelectionKey key = (SelectionKey) itr.next();
                itr.remove();
                SocketChannel ch = (SocketChannel) key.channel();
                if(key.isReadable())
                {
                    inputbuf.clear();
                    long bytesRead = ch.read(inputbuf);
                    inputbuf.flip();
                    byte[] test = inputbuf.array();
                    {
                        for(int i=0; i < inputbuf.remaining(); i++)
                        {
                           System.out.print(test[i]+" ");
                        }
                    }
                    byte cmd = 0;
                    cmd = inputbuf.get();
                    switch(cmd)
                    {
                        case 1:
                           //do something
                        case 2:
                           //do something else
                        break;
                    }
                }
                else if(key.isConnectable())
                {
                    sc.finishConnect();
                    sc.register(sel, SelectionKey.OP_READ);
                }
            }
        } catch (IOException ex) {
            Buildsim.error("Error handling input from server", ex);
        }
    }
}

Server code:

public RemotePlayer(SocketChannel s)
{
    sc = s;
    try {
        sel = Selector.open();
        sc.configureBlocking(false);
        sc.register(sel, SelectionKey.OP_WRITE);
        socket = sc.socket();
        ip = socket.getInetAddress().toString();
        System.out.println("New connection from "+ip);
        inputbuf = ByteBuffer.allocate(1048576);
        outputbuf = ByteBuffer.allocate(1048576);
        inputbuf.clear();
        outputbuf.clear();
    }
    catch(Exception e)
    {
        Buildsim.error("Connection error: ", e);
    }
    sendLevel();
}
public void sendObject(GameObject obj)
{
     //Sends a packet of the object, then does the same for the object's children
}
public void sendLevel()
{
    try {
        outputbuf.put((byte) 0x01);
        outputbuf.flip();
        sc.write(outputbuf);
        sendObject(Buildsim.w.parts.get(0)); //root object
    }
    catch(IOException e)
    {
        Buildsim.error("Error sending level to "+ip, e);
    }
}

The only thing that gets to the client is the byte 0x01 (signals a level change).

Thanks in advance.

A: 

With the amount of information you gave us, we can only give global hints, like: did you make sure your socket stream is not buffered and that you flush() after the information is written?

The data could be waiting in a buffer waiting to be filled to be sent.

Edit:

You set the SocketChannel to non-blocking mode, so you're right to assume that takes care of flushing on the sending side, I assume the client do not buffer their input?

The problem might be that SocketChannel.write() is not garantueed to write the whole buffer, but might return early. You need to wrap writes in a while loop to keeping track of bytes written to make sure your data is actually written to the channel. To quote the Javadoc:

Unless otherwise specified, a write operation will return only after writing all of the r requested bytes. Some types of channels, depending upon their state, may write only some of the bytes or possibly none at all. A socket channel in non-blocking mode, for example, cannot write any more bytes than are free in the socket's output buffer.

rsp
As you can see in the code, I'm using ByteBuffers to hold the data. I was under the impression that I didn't need to flush them, just use sc.write() to send the data in the buffer?
Jacob_