SFML community forums

Help => Network => Topic started by: egyware on October 27, 2012, 01:00:24 am

Title: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 27, 2012, 01:00:24 am
Hello everybody.


I'm using SFML 2.0 RC and I have this code, but doesn't wait doesn't work.

sf::SocketSelector selector;
        sf::UdpSocket socket;
        selector.add(socket);  
        sf::Packet p;
        p << 10; //arbitrary data

        socket.send(p,sf::IpAddress::getLocalAddress(),1010);

        selector.wait(sf::seconds(10)); //should wait 10 seconds       
        if(selector.isReady(socket))
        {
                sf::IpAddress ip;
                uint16 port;
                if(socket.receive(p,ip,port) == sf::Socket::Done)
                {
                        printf("Receive data\n");
                }
        }
        else
        {
                printf("Not ready\n");
        }
 

Some time ago using BSD Socket and WinSock and it worked. And not because it does not work if it should be like

Greetings!
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: wieduwillst on October 27, 2012, 01:52:00 pm
uint16 port;
if(socket.receive(p,ip,port) == sf::Socket::Done)
 

you have to set the port to the same you are sending (1010) in this case
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 27, 2012, 05:10:56 pm
The port specified in the send function can be different to the port specified in the receive function because it is automatically assigned by OS (or manually assigned)

I tried what you said, but nothing.

I think the real problem is located in SocketSelector, I'll have to look at the source code.
EDIT:(I check the source code, but I can't found any problem)

Thanks!
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 27, 2012, 06:50:49 pm
Is your socket bound to a port (socket.bind(...))?
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 27, 2012, 09:30:14 pm
Now I have this code, but doesn't work too  :(
sf::SocketSelector selector;
        sf::UdpSocket socket;  
        sf::Packet p;
        p << 10; //arbitrary data      
        socket.bind(1010);
        socket.send(p,sf::IpAddress::getLocalAddress(),1010);
        selector.add(socket);          
        printf("Emm....");
        selector.wait(sf::seconds(60));
        printf("...Yes\n");
       
        if(selector.isReady(socket))
        {
                sf::IpAddress ip;
                uint16 port=1010;
                if(socket.receive(p,ip,port) == sf::Socket::Done)
                {
                        printf("Data!!\n");
                }
        }
        else
        {
                printf("Not ready\n");
        }
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 27, 2012, 09:39:43 pm
What does "doesn't work" mean? What happens?
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 27, 2012, 11:09:05 pm
What does "doesn't work" mean? What happens?
:-X
...

The program doesn't wait a 60 seconds (or any time) when execute this line "selector.wait(sf::seconds(60))"
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 28, 2012, 11:52:41 am
Why should it wait? Since you send something, it immediately has something to receive.
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: binary1248 on October 28, 2012, 05:03:22 pm
After all the documentation says:

Quote
Wait until one or more sockets are ready to receive.

This function returns as soon as at least one socket has some data available to be received. To know which sockets are ready, use the isReady function. If you use a timeout and no socket is ready before the timeout is over, the function returns false.

So it waits either for a socket to become ready OR the timeout to expire whichever comes first. It does not have to wait for the timeout.

This is also standard behavior in all the other socket APIs out there.

Winsock:
Quote
timeout [in]
The maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations.

POSIX:
Quote
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 28, 2012, 08:39:59 pm
Why should it wait? Since you send something, it immediately has something to receive.

I'ts correct, but I change the destination port and nothing...

So it waits either for a socket to become ready OR the timeout to expire whichever comes first. It does not have to wait for the timeout.
This is also standard behavior in all the other socket APIs out there.

So the UDPSocket is always ready? I can't understand this because I don't send any data to socket.

I check my code and see some curiosities  :o

If I don't send anydata to localhost IT'S WORKS the program wait 60 seconds.
If I send anydata to localhost but to anyport the program(except 1010) don't wait 60 seconds but don't receive any data (of course).

This is a problem when code test the client and server.

Thanks  :)

Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 28, 2012, 08:48:58 pm
Can you please post a complete and minimal code that reproduces the problem?
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: egyware on October 28, 2012, 10:38:34 pm
Hello everybody.


I'm using SFML 2.0 RC and I have this code, but doesn't wait doesn't work.

sf::SocketSelector selector;
        sf::UdpSocket socket;
        selector.add(socket);  
        sf::Packet p;
        p << 10; //arbitrary data

        socket.send(p,sf::IpAddress::getLocalAddress(),1010);

        selector.wait(sf::seconds(10)); //should wait 10 seconds       
        if(selector.isReady(socket))
        {
                sf::IpAddress ip;
                uint16 port;
                if(socket.receive(p,ip,port) == sf::Socket::Done)
                {
                        printf("Receive data\n");
                }
        }
        else
        {
                printf("Not ready\n");
        }
 

Some time ago using BSD Socket and WinSock and it worked. And not because it does not work if it should be like

Greetings!


#include <cstdlib>
#include <SFML/Network.hpp>

int main(int argc, char **argv)
{
      sf::SocketSelector selector;
        sf::UdpSocket socket;
       
        sf::Packet p;
        p << 10; //arbitrary data

        if(socket.bind(3030) != sf::Socket::Done)
        {
                printf(":C no bind");
        }

        selector.add(socket);  

        socket.send(p,sf::IpAddress::getLocalAddress(),4030); //if remove this line, the program wait 10 seconds
        //socket.send(p,sf::IpAddress("192.168.1.31"),4040); //or use this line works!

        printf("...");
        selector.wait(sf::seconds(10)); //should wait 10 seconds       
        printf("...\n");
        if(selector.isReady(socket))
        {
                sf::IpAddress ip;
                uint16 port;
                if(socket.receive(p,ip,port) == sf::Socket::Done)
                {
                        printf("Receive data\n");
                }
                else
                {
                        printf("None\n");
                }
        }
        else
        {
                printf("Not ready\n");
        }
       
        system("pause");
}
 

This is a minimal code

Edit:Don't worry I will use the old implementation for this (with WinSock)
Thanks you!
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 28, 2012, 10:48:17 pm
Thanks. What's your OS, by the way?
Title: Re: Why doesn't work selector.wait with UDPSocket
Post by: Laurent on October 28, 2012, 11:04:15 pm
This is apparently a very specific behaviour on Windows: after sending to an unreachable port with a UDP socket, reading on this same socket returns a WSAECONNRESET status. So the selector marks it as "ready" (because the operation won't block), but there's nothing to read, just an error code to retrieve.

I don't know what should be done about this. There's a flag that I could use to disable this behaviour, but I'm not sure it's a clean solution. I have to read more about it.