UDP woes? Or a logic error?

I keep trying, lol. Now the client and server channels are unblocking, and I['ve got a few calls in while loops now. also I’m sending 2 instead of playerNum from the server for testing. Client still says it gets 0, even when not null?

Server:


import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
 
 
public class TestServer {
    DatagramChannel channel;
    SocketAddress player1IP;
    static int[] playerX;
    int enemy[];
     
    public void doStuff(){
        int playerNum = 0;
        playerX = new int[2];
        playerX[0] = 50;
        playerX[1] = 200;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
         
        channel = null;
        try {
            channel = DatagramChannel.open();
        } catch (IOException e3) {
            e3.printStackTrace();
        }
        SocketAddress address = new InetSocketAddress(4444);
        DatagramSocket socket = channel.socket();
        try {
            socket.bind(address);
        } catch (SocketException e3) {
            e3.printStackTrace();
        }
        
        try {
			channel.configureBlocking(false);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
        
        ByteBuffer buffer = ByteBuffer.allocate(255);
         
        while(playerNum < 2){
            SocketAddress client = null;
            try {
            	while(client == null){
            		client = channel.receive(buffer);
            	}
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
             
            if(!client.equals(player1IP)){
                if(playerNum == 0){ 
                    player1IP = client;
                }
             
             
                ByteBuffer sendBuf = ByteBuffer.allocate(255);
                System.out.println("#:"+playerNum);
                sendBuf.putInt(2);
                try {
                    channel.send(sendBuf, client);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 
                System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
                playerNum++;
                System.out.println("Incremented to: " + playerNum+ "\n");
            }
        }
         
        while(true){
            serverLoop();
        }
    }
     
    public void serverLoop(){}
     
    public static void main(String[] args){
        TestServer t = new TestServer();
        t.doStuff();
    }
}

Client


import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
 
 
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
 
public class TestClient extends BasicGame{
    int playerNum = 0;
    int[] playerX;
    int[] enemy;
     
    DatagramChannel channel;
     
    public  TestClient()
    {
        super("Test Client");
    }
     
    public static void main(String[] args) 
    throws SlickException
    {
         AppGameContainer app = 
            new AppGameContainer(new TestClient());
         
         app.setDisplayMode(640, 480, false);
         app.setTargetFrameRate(60);
         app.setAlwaysRender(true);
         app.start();
    }
 
    @Override
    public void render(GameContainer gc, Graphics g) throws SlickException {
        g.drawString("px:" + playerX[playerNum], 10, 10);
        g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
        g.drawString("p#:" + playerNum, 10, 40);
    }
 
    @Override
    public void init(GameContainer gc) throws SlickException {
        playerX = new int[2];
        playerX[0] = 0;
        playerX[1] = 0;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
         
        try{
            channel = DatagramChannel.open();
            SocketAddress address = new InetSocketAddress(0);
            DatagramSocket socket = channel.socket();
            socket.bind(address);
             
            SocketAddress server = new InetSocketAddress("76.121.76.188", 4444);
            channel.connect(server);
            
            channel.configureBlocking(false);
             
            ByteBuffer sendBuf = ByteBuffer.allocate(255);
            sendBuf.put((byte) 0);
            channel.send(sendBuf, server);
             
            ByteBuffer receiveBuf  = ByteBuffer.allocate(255);
            while(channel.receive(receiveBuf) == null);
            this.playerNum  = receiveBuf.getInt();
            System.out.println("#:"+this.playerNum);
             
             
        }
         
        catch(Exception e){
            e.printStackTrace();
        }
    }
 
    @Override
    public void update(GameContainer gc, int delta) throws SlickException {
        Input input = gc.getInput();
         if(input.isKeyDown(Input.KEY_A))
            {
                playerX[playerNum]-=2;
            }
      
            if(input.isKeyDown(Input.KEY_D))
            {
                playerX[playerNum]+=2;
            }
    }
}

Ok multiple things:

  1. don’t forget to set the SocketAdress client variable in TestServer to null so you can enter that while loop again.
  2. Because this a non-blocking channel, calling receive() in TestClient doesn’t guarantee that data will be available, so you’ve got to put it another while loop:

while(channel.receive(receiveBuff) == null) {
    Thread.yield();
}

So all fixed?

Yeah. You have to .flip() your bytebuffer before sending and after receiving it. lol

Cool, glad to see you got it working. Sorry I wasn’t able to look at it until you already had it done. :slight_smile:

Hey how come he gets a medal >:(
(jk :stuck_out_tongue: )

But that’s just weird, why call “flip()” when you receive it? O.o

The reason Java is named as such is because Games Josling, who invented Java, used to live in the country of Java where he DID NOT drink coffee, he had hot chocolate. It’s a common misunderstanding that it’s based off coffee, the logo for Java is actually the shape of the country, NOT a coffee cup. And the steam rising is the vapors rising from the dense population of the country.

Ah thanks for for you help. However, it would make more sense if the receive() method did that since it is just doing “put(byte)” length number of times.

Here how data sends in theory .You send :
Data 1
Data 2
Data 3
Client receive:
Data 1
Data 2
Data 3
But on practice data may be lost or will be received in not right order (lags in network)
If you want filter data manually you can add to send Data : time of sending , packet number ,
Or any else information that you need :wink:
I don’t have many experience in Socket programming (only program http sending and some multi thread TCP client-server;))

Actually that is totally wrong.

On a reliable connection packets arriove in the order they were sent. In a non-reliable, they arrive in any order.

But within the packet you need to read the data out in the same order you wrote it in. If you actually RTFM you find out that flip doesnt do what you think it does.

When you finish writing into the buffer, you are in “just written” state. Your current position is the byte just after the last one you wrote (the next place to write if you continued writing) and your limit is the last byte in the buffer.

Flip puts you into “ready to read state” by putting the current position into the limit so you cannot read past what you wrote, and then putting 0 into current position as this is the place you want to start reading from.