Reputation: 2305
I am using select()
, and NONBLOCKING
connection fd to accept connections and handle input and output. I am having some issue handling large data transfer of more than the buffer size. So for example here:
readCount = 1;
while(readCount > 0)
{
// clear t_input to read new data from the fd
memset(t_input, 0, CLIENT_INPUT_BUFF_LEN);
// read data from the client connectionFd and since t_input is 1024 only
// read that much
readCount = read(iter->connectionFd, t_input, 1024);
printf("<<< %d - %s >>> \n", errno, strerror(errno));
if(readCount == -1)
{
if( errno == EAGAIN)
break;
}
iter->AppendInputData(t_input, readCount);
}
This doesn't work for large data. So when I transfer data that is less than 1024
, The first read
call successfully finishes and data is copied in the AppendInputData
call. Since it's in a loop, the second read
call returns -1
, and set's errno
to EAGAIN
which then breaks the loop - all is good for this case.
However, in the case of larger than 1024
data, the second read calls fails again and errno
is set to EAGAIN
. The weird thing is, in debug mode, I don't see this behavior and the second or third read
call returns fine and all data is collected. Can someone explain what might be happening?
Upvotes: 0
Views: 545
Reputation: 310840
It's all timing. You can't assume that all the data will arrive continuously and be available whenever you call read(), or that when EAGAIN occurs that's the end of it forever. It is customary to call select() to tell you when data is available to read.
You get a different behaviour in debug mode because you're altering the timing.
Upvotes: 2
Reputation: 595295
Try something more like this instead:
do
{
// read data from the client connectionFd and since t_input is 1024 only read that much
readCount = read(iter->connectionFd, t_input, 1024);
if (readCount == -1)
{
if (errno == EAGAIN)
{
fd_set fd;
FD_ZERO(&fd);
FD_SET(iter->connectionFd, &fd);
timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
readCount = select(iter->connectionFd+1, &fd, NULL, NULL, &tv);
if (readCount == 1)
continue;
if (readCount == 0)
{
printf("<<< timeout >>> \n");
break;
}
}
printf("<<< %d - %s >>> \n", errno, strerror(errno));
break;
}
if (readCount == 0)
{
printf("<<< disconnect >>> \n");
break;
}
iter->AppendInputData(t_input, readCount);
}
while (true);
Upvotes: 2