Solved

ioctlsocket reporting 0 bytes available to read

Posted on 2011-09-15
2
922 Views
Last Modified: 2012-06-21
I'm trying to track down an issue I have with windows sockets.

I have an client and server which I use to send simple text commands data back and forth.

I have a non-blocking socket which I use to send data from my client to the server

int err = send( socket, stringToSend.c_str(), stringToSend.size(), 0 );

Open in new window


I then use the following to check if there is any data on the socket to read:


if (SOCKET_ERROR != ioctlsocket( socket, FIONREAD, (DWORD*)&nLength ))
{
    if (0 < nLength)
    {
         err = recv( socket, buf, nLength, 0 );

         //blah blah
    }

        //blah blah
}

Open in new window



Now I have a strange problem.
1. When I send the first piece of data from client to server I am able to receive a response from the server.
2. Then I try to send the smae piece of data again, but this time ioctlsocket always reports that no 0 bytes are available to read from the socket (nLength is always 0).

The strange thing is that if I use wireshark I can see that the server has actually sent data to the client.

What would cause ioctlsocket to report that nLength = 0 whenever I can see data sent via wireshark???

Thanks
0
Comment
Question by:Wanting2LearnMan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 8

Accepted Solution

by:
ssnkumar earned 250 total points
ID: 36547309
The prototype of ioctlsocket() is like this:
int ioctlsocket(__in     SOCKET s, __in     long cmd, __inout  u_long *argp);

The 3rd argument *argp is "A pointer to a parameter for cmd".
Set *argp to a nonzero value if the nonblocking mode should be enabled
OR
set it to 0 if the nonblocking mode should be disabled.

In your case, I think you are not setting any value to it - you are actually waiting for it to return some value.
So, what might be happening is:
Firsttime when client sends data to server and receives back the response, the value stored in nLength was 0.
And it returned a non-zero positive value back.
Now, when you are calling the ioctlsocket() 2nd time, it is using the non-zero positive value that was set in the previous call.
Because of that, it has become a non-Blocking call and returning immediately.
So, try to explicitly set it to 0 before the 2nd call also and see what happens.

I am assuming that you are checking the value of err returned from ioctlsocket().
It should be 0 to indicate success.
If it is non-zero, then use WSAGetLastError to find the error code - that might throw some clue.

So, the first thing that you should try is to, set nLength to 0 before each call to ioctlsocket, like this:

 
nLength = 0;
if (SOCKET_ERROR != ioctlsocket( socket, FIONREAD, (DWORD*)&nLength ))
{
    if (0 < nLength)
    {
         err = recv( socket, buf, nLength, 0 );

         //blah blah
    }

        //blah blah
}

Open in new window

0
 
LVL 34

Assisted Solution

by:sarabande
sarabande earned 250 total points
ID: 36548037
the blocking enabling and disabling was done with option FIONBIO and not FIONREAD.

i assume FIONREAD doesn't work properly with non-blocking sockets. you simply should do recv whcih would not block and mostly would return -1 with WSAGetLastError() is WSAEWOULDBLCK.

Sara
0

Featured Post

Enroll in June's Course of the Month

June's Course of the Month is now available! Every 10 seconds, a consumer gets hit with ransomware. Refresh your knowledge of ransomware best practices by enrolling in this month's complimentary course for Premium Members, Team Accounts, and Qualified Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

695 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question