Click to See Complete Forum and Search --> : recv (winsock2)
avi123
February 29th, 2004, 10:12 AM
Hi,
I'm using these winsock2 functions:
Sock= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Sock == INVALID_SOCKET)
{
//error
}
connect(Sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR_IN)) != SUCCESS)
{
//error
}
I have 2 questions:
1. I want to use blocking mode should I use:
unsigned long ulFlag = 0;
ioctlsocket(Sock, FIONBIO, &ulFlag);
or is it the default mode?
fot the meanwhile I call it but maybe it's not necessary
2. I call recv and get 0, I know that the server doesn't send me anything at this point, so I think 0 error code is not what should happen
If I understand correctly blocking mode, than recv shouldn't come back until the server will send data or the server will shut down the connection (and then I need to get 0, but this is not the case here)
anyone has an idea why does recv return 0?
thank you very much
I'm desperet here....
avi
j0nas
February 29th, 2004, 11:10 AM
1. Yes, blocking mode is the default. No need to call ioctlsocket.
2. recv() returns zero when the other end shut down the connection gracefully. I other words, your app has received all data it can and the other end has closed the socket.
avi123
February 29th, 2004, 11:20 AM
thanks
but I have a problem with question 2
I call socket and connect and the I call recv and get 0
I call recv again and again get 0
if the server has shut down gracefully shouldn't I get an error on the second time?
plus I know the server didn't shut down gracfully (didn't shut down) so why did I get 0?
is it possible that for some reason I am not in blocking mode, and since the server hasn't sent anything (I know the server didn't send a thing) then I got 0?
Do you happen to have a simple example of a client application, that just do call socket, connect and then an infintie loop of recv?
thanks
avi
Andreas Masur
February 29th, 2004, 01:47 PM
[Moved thread]
j0nas
February 29th, 2004, 05:20 PM
Originally posted by avi123
but I have a problem with question 2
I call socket and connect and the I call recv and get 0
I call recv again and again get 0
if the server has shut down gracefully shouldn't I get an error on the second time? Unless you close the socket after the first time recv() returns 0, this is fully correct.
Originally posted by avi123
plus I know the server didn't shut down gracfully (didn't shut down) so why did I get 0?
Calling closesocket() is enough. It's however considered good practice to call shutdown() before closing a socket.
Originally posted by avi123
is it possible that for some reason I am not in blocking mode, and since the server hasn't sent anything (I know the server didn't send a thing) then I got 0? No. Take a look at both your server and client code again. There must be some kind of bug in there... Or, maybe, a problem with your network.
Originally posted by avi123
Do you happen to have a simple example of a client application, that just do call socket, connect and then an infintie loop of recv?No, but such program would be easy to create. Write it and then post it here, and I'll be more than happy to have a look at it.
Hope it helps,
Jonas
Mathew Joy
February 29th, 2004, 11:37 PM
Additionaly this link (http://tangentsoft.net/wskfaq/examples/basics/) provides basic example. Might help you.
avi123
March 1st, 2004, 01:05 AM
well basically that's what I do: (my code)
the recv akways return 0, any idea why?
int CMyConnection::Init()
{
SOCKADDR_IN sockAddr1; //address1
SOCKADDR_IN sockAddr2; //address2
int iErr;
//1
//create a socket for 1
m_Sock1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_Sock1 == INVALID_SOCKET)
{
//handle error
}
//use blocking
unsigned long ulFlag = 0;
DWORD dwError = ioctlsocket(m_Sock1, FIONBIO, &ulFlag);
sockAddr1.sin_family = AF_INET;
sockAddr1.sin_addr.S_un.S_addr = inet_addr (ConnectionStruct.szAddress);
sockAddr1.sin_port = htons(ConnectionStruct.iPort);
if (iErr = connect(m_Sock1, (SOCKADDR*)&sockAddr1, sizeof(SOCKADDR_IN)) != SUCCESS)
{
//handle error
}
m_hthread1handle = CreateThread(NULL, NULL, Thread_1, this, NULL, &m_dwId1);
//same for 2....
}
DWORD __stdcall CMyConnection::Thread_1(LPVOID lpContext)
{
int iLen = -1;
CMyConnection* pThis; //context pointer
//get the context pointer from the parameter
pThis = reinterpret_cast<CMyConnection*>(lpContext);
//allocate the buffer size
char* szBuffer = new char[BUFFER_SIZE];
//read from socket
while(true)
{
//this recv always return 0, why?
iLen= recv(pThis->m_Sock1, szBuffer, BUFFER_SIZE, NULL);
}
//free buffer
delete szBuffer;
}
Mathew Joy
March 1st, 2004, 01:10 AM
Despite of correcting you many times why are you making the socket non-blocking by using ioctlsocket()?? :mad:
avi123
March 1st, 2004, 01:30 AM
From reading in the MSDN if I give a value of 0 to ulFlag it's blocking and non zero is non blocking
anyway even if I remove the statment:
DWORD dError = ioctlsocket(m_SockMOF, FIONBIO, &ulFlag);
recv still returns 0
thanks
P.S beside that habe you looked at the code?
Is there something else that might be wrong?
I'm begining to be desperet
avi
Mathew Joy
March 1st, 2004, 01:43 AM
OK OK. Even if it is non-blocking it is not supposed to return 0 more than once. And the server side? Maybe the relevent error might not be in what you quoted.
avi123
March 1st, 2004, 02:09 AM
I'm using blocking!
forget the ioctlsocket, let's say it doesn't exist
in blocking mode, is it ok to get 0 and then again 0?
I don't write the server side, it was written long time ago, and used to work with an asynchronic (non blocking) vb client
now I'm doing a new C++ client which is synchronuc & blocking (or at least suppose to ...)
thanks (don't give up on me :) )
Mathew Joy
March 1st, 2004, 02:31 AM
Yes, you are using blocking! Since you are not writing the server, I suggest you to write a simple server and test your client before connecting to the server. Normally, when you get 0, that means the peer is closed and you also close the socket. However, getting another 0 might be possible in certian circumstance. The only other situation I see is when the buffer size is given as 0. Each winsock API call should be checked for possible error (SOCKET_ERROR) also. (I didn't see in your code)
:thumb:
j0nas
March 1st, 2004, 04:26 AM
Originally posted by Mathew Joy
However, getting another 0 might be possible in certian circumstance.
This is interesting. You say that calling recv() a second time, after it has returned 0, shouldn't work or shouldn't return zero?
Where did you get that info from?
I'm not saying you're wrong. I'm only interested in where this is stated.
/Jonas
Mathew Joy
March 1st, 2004, 05:21 AM
Not very sure either. ISTR reading somewhere...but not sure. That's why I included in the post that normaly you close the socket knowing that you peer is closed.
simpleman
March 1st, 2004, 05:53 AM
hi avi123
I am simpleman
i think the problem is that why the return value of recv() is always Zero.
think like that.. everybody knows that the connection was closed gracefully if the return value is Zero.
it means server side closed the connection gracefully. so i think it is good idea trying as following..
1. make a break point before send some data
2. check the connection status with "netstat -an"
3. if the connection is ok then send the data to server
4. make another break beofre recv()
5. check the connection status with "netstat -an"
i think you do step 4 and 5 a lot of time. but i think you can check if the connection is closed by server side before calling recv() or not.
if you find CLOSE_WAIT from the server before calling recv(), i think you should ask it to server programer.
it could be possible that if your sending(request) data is wrong data, the server application could cut the connection. (actually it is my coding style) so will you ckeck the packet definition carefully? ^^
Good Luck for you..
Mathew Joy
March 1st, 2004, 06:38 AM
I don't think these steps are necessary. The op might have to know the functions of the server to know why it closed the connection. CLOSE_WAIT is a state of the socket, not something we get from the peer. The socket changes to this state when it gets a FIN packet from the peer indicating it is shutting down.
codeguru.com
Copyright 2007 Jupitermedia Corporation All Rights Reserved.