connect and send on the socket succeeds, even if WIFI not enabled and server is only reacheable in the wireless network - Windows Mobile 6.5 - C/C++

喜欢而已 提交于 2020-01-24 20:30:47

问题


I wrote a small C/C++ Windows Mobile 6.5 client-application that is connecting to a server and sends some data to this server. The server is in my internal wireless network and is not reacheable outside.

The weird behaviour I'm having:

1) Even if the WIFI is not started on my mobile device, the connect() from the client-application returns success (!= SOCKET_ERROR), which is not the case b/c the server is reacheable only in the wireless network.

2) If the WIFI is not started on my mobile device, if there is a Sleep(1000) between the connect() and the send(), the send() fails with WSAECONNRESET, BUT if there is no Sleep() between the connect() and send() the send() succeeds! (only when doing the read() I finally get the WSAECONNRESET error).

Can somebody pls point me some tips why do I have this behaviour. It's pretty scary that without actually being able to reach the server I still get success for the connect() and for the send() :(

As requested, here is a sample code:

#include <windows.h>
#include <Winsock2.h>
#include "dbgview.h"

#   define FxMemZero(buf,len)       RtlZeroMemory ((VOID*)(buf),(SIZE_T)(len))
#   define FxMemCopy(dst,src,len)   RtlCopyMemory ((VOID*)(dst),(CONST VOID*)(src),(SIZE_T)(len))


int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{

    SOCKET proxy_connection;
    WSADATA wsadata;
    if( 0 != WSAStartup (MAKEWORD(1, 1), &wsadata))
        return -1;

    proxy_connection = WSASocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
    if(proxy_connection == INVALID_SOCKET) {
        // error creating the socket
        DbgViewTraceError((L"main", L"error creating socket."));
        return -1;
    }
    // try to connect
    UINT proxy_ip_ = 0x00000000;
    CHAR* proxy_0_ =  "192.168.1.105";
    UINT proxy_port = 3100;
    // get the proxy ip
    {
        struct hostent *he_;
        if((he_ = gethostbyname(proxy_0_)) == NULL) {
            DbgViewTraceWarning((L"main", L"error %d resolving hostname %hs", WSAGetLastError(), proxy_0_));
            return -1;
        }
        FxMemCopy((PBYTE)&proxy_ip_, (PBYTE)he_->h_addr, he_->h_length);
    }
    // prepare the connection data
    sockaddr_in saddr_;
    FxMemZero(&saddr_,sizeof(sockaddr_in));
    saddr_.sin_family = AF_INET;
    saddr_.sin_addr.S_un.S_addr = proxy_ip_;// address
    saddr_.sin_port = htons((USHORT)proxy_port);
    // do the conection
    if(SOCKET_ERROR == connect(proxy_connection, (SOCKADDR*) &saddr_, sizeof(saddr_))) {
        // error connecting to the proxy
        DbgViewTraceWarning(( L"main", L"error %d connecting to %hs:%d", WSAGetLastError(), proxy_0_, proxy_port));
        closesocket(proxy_connection);
        proxy_connection = INVALID_SOCKET;
        return -1;
    }
    DbgViewTraceInfo(( L"main", L"SUCCESS. connected to %hs:%d.", proxy_0_, proxy_port));


    CHAR* buffer_ = "Momo";
    UINT  count_  = strlen(buffer_);
    DWORD total_  = 0;
    DWORD sent_   = 0;
    while(total_ < count_) {
        // ISSUE: IF the WIFI is not started on the mobile, the connect returns success AND the send() returns success, even though with putty
        //   on the mobile, a telnet on 192.168.1.105:3100 will fail with: "Network error: Connection reset by peer"
        //   IF I add a long-enough Sleep() between the connect() and the send(), the send() will fail with: WSAECONNRESET
        //Sleep(5000);
        if(SOCKET_ERROR == (sent_ = send(proxy_connection, (const char*)buffer_ + total_, count_ - total_, 0))) {
            // error sending data to the socket
            DbgViewTraceError((L"main", L"error %d sending data to proxy", WSAGetLastError()));
            return -1;
        }
        total_ += sent_;
    }
    DbgViewTraceInfo((L"main", L"send() SUCCESS"));
    return 0;
}

The results are:

1) Without Sleep():

main [INFO ] SUCCESS. connected to 192.168.1.105:3100.

main [INFO ] send() SUCCESS

2) With Sleep():

main [INFO ] SUCCESS. connected to 192.168.1.105:3100.

main [ERROR ] error 10054 sending data to proxy

So the questions are:

1) Why the connect() succeeds? How can I be sure that there is actually a real connection?

2) Why the send() succeeds?

3) Why with a Sleep() in between connect() and send() the behaviour is different?


The problem seems to be ActiveSync. If ActiveSync is running, I get the behavior described above (connect() and send() report success, even though they are not). If ActiveSync is not running, gethostbyname() fails with:

  • WSAENETDOWN -> if WIFI is disabled

  • WSAHOST_NOT_FOUND -> if WIFI is enabled

which is correct!

How can this be? What is ActiveSync doing that is ruining everything? How can I avoid this problem? I mean, I can't be sure that the user is running my application when there is no ActiveSync running, so what can I do to avoid this behavior when ActiveSync is running?

Thx, MeCoco


回答1:


Looks like you are at least misusing struct sockaddr_in. Try more modern API for address conversion - Windows has InetPton - and see if that fixes the issues.



来源:https://stackoverflow.com/questions/6573257/connect-and-send-on-the-socket-succeeds-even-if-wifi-not-enabled-and-server-is

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!