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.
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.
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 (!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.