Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - addisonElliott

Pages: [1]
1
Feature requests / Re: Select function
« on: June 07, 2015, 04:11:59 am »
I have implemented my own class that does what I would like. However, I will consider switching over to SFML's networking if they provide this Select function.

I will show my Select function code to demonstrate the usefulness.

void Socket::Select(double timeout)
{
    if (!connected && !isConnecting)
        return;

    fd_set readFds, writeFds, exceptFds;
        long tsecs = long(timeout);
        timeval timeoutVal = {tsecs, long((timeout - double(tsecs))*1000000)};

        FD_ZERO(&readFds);
        FD_ZERO(&writeFds);
        FD_ZERO(&exceptFds);

    FD_SET(impl->sock, &readFds);
    if (isConnecting || sendBuffer.length() > 0)
        FD_SET(impl->sock, &writeFds);
    FD_SET(impl->sock, &exceptFds);

        int result = select(impl->sock+1, &readFds, &writeFds, &exceptFds, &timeoutVal);
        if (result == SOCKET_ERROR)
            return;

        if (result > 0)
        {
                if (FD_ISSET(impl->sock, &exceptFds))
                {
                    // If attempting to connect, this means it failed
                    // Otherwise it means there was an error with the socket somehow
                    isConnecting = false;
                    EmitMainEvent(Event::NetworkConnectTerm);
                    return;
                }

                if (FD_ISSET(impl->sock, &writeFds))
                {
                    if (isConnecting)
            {
                // If attemtping to connect, this means that it succeeded
                connected = true;
                EmitMainEvent(Event::NetworkConnectOk);
                isConnecting = false;
                return;
            }
                        else if (!DoSend())
                        {
            // Otherwise it means you are able to write data without it blocking.
            // I have a string buffer for sending and receiving data, and so DoSend just removes some data from the buffer and sends it.  
           // At least 1 byte of data should be sent, otherwise it means there was an error of some sort.
                            Close();
                            EmitMainEvent(Event::NetworkConnectTerm);
                                return;
                        }
                }

                if (FD_ISSET(impl->sock, &readFds))
                {
                        if (!DoRecv())
                        {
               // This means there is data to be read. If no data is able to be read, this means that the socket was most likely closed.
                            Close();
                            EmitMainEvent(Event::NetworkConnectTerm);
                                return;
                        }
                }
        }
}

If you read the MSDN on the select function, there are special cases that indicate whether a connection was successful or was terminated in which I noted in the comments. I am not sure how this ports over to other operating systems.

2
Feature requests / Re: Select function
« on: June 06, 2015, 04:23:16 pm »
From as far as I can tell, the sf::SocketSelector class is meant for multiple sockets at once. Even then, the class only notifies you that it is ready to receive data. The select function would notify you if there was an error, if you are ready to receive, and if it is capable of writing.

3
Feature requests / Select function
« on: June 06, 2015, 06:43:48 am »
Hello,
I would like to request that a Select function be added to the TcpSocket class. The main benefit of this would be for programmers who are utilizing non-blocking.

In my case, I am working on a game that needs to be responsive at all times. This means that the connect, receive, or send functions cannot be blocking. Here is how I would like to do it:
while (running)
{
    sf::TcpClient::Status status = socket.Select();
    if (status & sf::TcpClient::Write)
    {
          socket.Send(buffer);
    }
   
    if (status & sf::TcpClient::Read)
    {
          socket.Recv(buffer);
    }

    if (status & sf::TcpClient::Error)
    {
          Error.
    }
    // Other game stuff
}

The current way to achieve this is to continually call connect, in which the host & port parameters are required everytime. Then once you are connected, you call send/recv in the hopes that data is there or that it is able to send data. The reason why I would like the select function is because it is one function that will tell you if there was an error, if its ready to send data, and if it has data waiting to be received.

A problem I see with my proposed implementation of the Select function is that you are 'doubling' up on error checking. Currently, WSAGetLastError is called in the connect, recv, and send functions to report any error. But then you are calling Select which will report if there is an error there as well. This doesn't have a huge affect on anything, but it is unnecessary to do this.

Since SFML does not offer what I need, I have my own wrapper which does the same thing effectively. I would prefer to use SFML's networking class just to be consistent since the rest of the game uses it.

Pages: [1]