Archived

This topic is now archived and is closed to further replies.

async -> non-blocking

This topic is 4983 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been using async sockets for a while now, and are considering to merge to non-blocking sockets instead. The reasons are performance and portability. Is it difficult to learn non-blocking sockets when you have blocking sockets and async sockets background? I think non-blocking code looks like sh*t unfortunatly

Share this post


Link to post
Share on other sites
The main change with non-blocking sockets compared to blocking sockets is, obviously, that they won''t block. That means that you must be ready to handle the case where your network operations failed because it would have blocked (EINPROGRESS or EWOULDBLOCK, depending on OS and function, IIRC). It means, in the case of a send() that you''ll have to buffer your unsent data (a block on recv() means that there''s no data to be read, which is trivial to handle, as I see it), and progressively empty it with each successful send() (on a partial send, you will be told how much data was successfully sent).

All in all, aside for a couple of tricky issues (mostly because I haven''t bothered reading about how to deal with them) involving non-blocking listening sockets, I don''t think non-blocking IO is that complicated - if you understand buffering, that is.

Short of using non-blocking sockets, polling with select() is an ever popular choice.

Share this post


Link to post
Share on other sites
From my socket code (uses select()):

bool CDataSocket::Receive(DWORD dwTimeout/*=0*/)
{
char pBuffer[512];
int nLen;
fd_set theSet;
timeval theTimeout;
int nResult;
bool bReceived = false;

// Check for valid data //

if(m_sock == INVALID_SOCKET)
return false;

do
{
// Setup select() Structures //

FD_ZERO(&theSet);
FD_SET(m_sock,&theSet);
theTimeout.tv_sec = dwTimeout/1000;
theTimeout.tv_usec = (dwTimeout-(theTimeout.tv_sec*1000))*1000;

// See if we can recv() //

nResult = select(m_sock+1,&theSet,NULL,NULL,&theTimeout);
if(nResult == SOCKET_ERROR)
{
m_strError = "Warning, select(recv) failed. Result = " + IntToString(nResult) + ", " + WSAErrorAsString(Error);
Disconnect();
return bReceived;
}
else if(nResult != 1)
{
return bReceived;
}

// Read data //

nLen = recv(m_sock,pBuffer,512,0);
if(nLen <= 0)
{
if(nLen == 0)
m_strError = "The remote machine closed the connection";
else if(Error != 0)
m_strError = "recv() failed. " + WSAErrorAsString(Error);
else
m_strError = "recv() failed";
Disconnect();
return bReceived;
}
nResult = m_vBuffer.size(); // Old Size

m_vBuffer.resize(nResult+nLen);
CopyMemory(&m_vBuffer[nResult],pBuffer,nLen);
bReceived = true;
} while(nLen == 512);
return true;
}


May or may not help...

Share this post


Link to post
Share on other sites
You should have no problem working with non-blocking I/O. The key to understanding non-blocking I/O is control. The OS gives you control with regards to analyzing incoming and outgoing data.

Kuphryn

Share this post


Link to post
Share on other sites