Discussion:
How to handle connect error: WSAEINVAL ?
(too old to reply)
wangyouhua
2003-07-07 02:24:01 UTC
Permalink
In my App, i try to connect to an fixed address and port. It check
connection by interval, and call Connect() if the connection was break.

BOOL CMyAsyncSocket::Connect(const SOCKADDR *lpSockAddr, int nSockAddrLen)
{
ASSERT(m_hSocket!=INVALID_SOCKET);

unsigned long arg = 1;
ioctlsocket(m_hSocket, FIONBIO, &arg);

connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;

int nError = GetLastError();
return ( (nError== WSAEWOULDBLOCK) ? 1 : 0 );
}

If the Server(on remote station) is started for the first time, then my App
call CMyAsyncSocket::Connect() correctly(GetLastError()==WSAEWOULDBLOCK).

If i the Server is stop and then start. Because it found that connection was
break, My App handle the OnClose and create a new client socket and then
call CMyAsyncSocket::Connect() secondly . But this time, GetLastError
function in CMyAsyncSocket::Connect() return a value: WSAEINVAL.


Can anyone give my some hints to solve this problem?

Thanks.
Joseph M. Newcomer
2003-07-07 06:23:52 UTC
Permalink
What is that nonsense about ioctsocket? I see a class derived from CAsyncSocket, and
therefore there is no need to set it to being an asynchronous socket.

I believe this declares a BOOL value. What is the purpose of returning an integer? Would
it not make more sense to return TRUE or FALSE? Coding integer values like this is
incredibly sloppy programming. For that matter, why are you writing code as clumsy as what
you show here. Why not say

return nError == WSAEWOULDBLOCK;

Note that return is not a function, and therefore does not need to have its expression in
parentheses. What you wrote was:
compute a boolean value. If the boolean value is non-FALSE, return a numeric
constant 1 and if the boolean value is FALSE return a numeric constant 0.

Yet the correct code is to simply compute the boolean expression and return it. And of
course, it would never make sense to return a numeric constant to represent a logical
value.

Exactly why you are calling the low-level connect method of winsock instead of
CAsyncSocket::Connect also escapes me. Then you compare it to SOCKET_ERROR and do nothing
other than throw the result of this meaningless comparison away. And you are testing
GetLastError based on some bizarre belief that it will be meaningful if the operation
succeeds; this is rarely if ever true. If the operation succeeds, the value of
::GetLastError is often undefined, unless the code explicitly states it is defined.

BOOL CMyAsyncSocket::Connect(const SOCKADDR * lpSockAddr, int nSockAddrLen)
{
ASSERT(m_hSocket != INVALID_SOCKET);
if(CAsyncSocket::Connect(lpSockAddr, nSockAddrLen))
return TRUE;
return ::GetLastError() == WSAWOULDBLOCK;
}

This eliminates all the nonsense code that redundantly sets nonblocking mode, calls the
connect method correctly, and properly handles the cases of success and failure. And
returns types consistent with the return type.

WSAEINVAL means that you passed an invalid parameter. For example, any of the parameters
in the SOCKADDR structure could be incorrect. Did you check to see if they are properly
set up? Did you compare them to the parameters used the previous time? I don't see the
initialization that is being performed, which is most likely where the error is occurring.
But the code that I do see posesses properties of being unnecessary, inappropriate, and/or
incorrect, so I'd suggest fixing all those problems first. And it makes me suspicious of
other problems (for example, a tendency to call low-level functions instead of the methods
of the class here indicates that you might be equally well doing it elsewhere, which leads
to conjectures about similar problems elsewhere). So showing your OnClose handler would be
useful as well. I suspect problems there.
joe
Post by wangyouhua
In my App, i try to connect to an fixed address and port. It check
connection by interval, and call Connect() if the connection was break.
BOOL CMyAsyncSocket::Connect(const SOCKADDR *lpSockAddr, int nSockAddrLen)
{
ASSERT(m_hSocket!=INVALID_SOCKET);
unsigned long arg = 1;
ioctlsocket(m_hSocket, FIONBIO, &arg);
connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
int nError = GetLastError();
return ( (nError== WSAEWOULDBLOCK) ? 1 : 0 );
}
If the Server(on remote station) is started for the first time, then my App
call CMyAsyncSocket::Connect() correctly(GetLastError()==WSAEWOULDBLOCK).
If i the Server is stop and then start. Because it found that connection was
break, My App handle the OnClose and create a new client socket and then
call CMyAsyncSocket::Connect() secondly . But this time, GetLastError
function in CMyAsyncSocket::Connect() return a value: WSAEINVAL.
Can anyone give my some hints to solve this problem?
Thanks.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Loading...