подключение и отправка через сокет завершаются успешно, даже если WIFI не включен и сервер доступен только в беспроводной сети - Windows Mobile 6.5 - C / C ++

Я написал небольшое клиентское приложение C / C ++ для Windows Mobile 6.5, которое подключается к серверу и отправляет некоторые данные на этот сервер. Сервер находится во внутренней беспроводной сети и недоступен снаружи.

У меня странное поведение:

1) Даже если WIFI не запущен на моем мобильном устройстве, connect () из клиентского приложения возвращает успех (! = SOCKET_ERROR), что не так, потому что сервер доступен только в беспроводной сети.

2) Если WIFI не запущен на моем мобильном устройстве, если между connect () и send () есть Sleep (1000), send () завершится с ошибкой WSAECONNRESET, НО если нет Sleep () между connect () и send () send () завершается успешно! (только при выполнении read () я наконец получаю ошибку WSAECONNRESET).

Может ли кто-нибудь дать мне несколько советов, почему у меня такое поведение. Довольно страшно, что, фактически не имея возможности связаться с сервером, я все равно добиваюсь успеха для connect () и для send () :(

По запросу, вот пример кода:

#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;
}

Результаты следующие:

1) Без сна ():

главная [ИНФОРМАЦИЯ] УСПЕХ. подключен к 192.168.1.105:3100.

главная [ИНФОРМАЦИЯ] send () УСПЕХ

2) Со сном ():

главная [ИНФОРМАЦИЯ] УСПЕХ. подключен к 192.168.1.105:3100.

основная ошибка [ERROR] 10054 отправка данных на прокси

Итак, вопросы:

1) Почему удалось выполнить connect ()? Как я могу быть уверен, что действительно существует настоящая связь?

2) Почему send () завершается успешно?

3) Почему при использовании Sleep () между connect () и send () поведение отличается?


Проблема, похоже, в ActiveSync. Если ActiveSync запущен, я получаю описанное выше поведение (connect () и send () сообщают об успехе, хотя это не так). Если ActiveSync не запущен, gethostbyname () завершится ошибкой:

  • WSAENETDOWN -> если WIFI отключен

  • WSAHOST_NOT_FOUND -> если WIFI включен

что правильно!

Как это может быть? Что делает ActiveSync, что все портит? Как я могу избежать этой проблемы? Я имею в виду, я не могу быть уверен, что пользователь запускает мое приложение, когда ActiveSync не запущен, так что я могу сделать, чтобы избежать такого поведения при запущенном ActiveSync?

Спасибо, MeCoco


person Viv Coco    schedule 04.07.2011    source источник
comment
Можете ли вы опубликовать реальный код?   -  person ctacke    schedule 04.07.2011


Ответы (1)


Похоже, вы по крайней мере неправильно используете struct sockaddr_in. Попробуйте более современный API для преобразования адресов - в Windows есть InetPton - и посмотрите, решит ли это проблемы.

person Nikolai Fetissov    schedule 05.07.2011