即使未启用 Wi-Fi 并且只能在无线网络中访问服务器,在套接字上连接和发送也会成功 - Windows Mobile 6.5 - C/C++

问题描述 投票:0回答:1

我编写了一个小型 C/C++ Windows Mobile 6.5 客户端应用程序,它连接到服务器并向该服务器发送一些数据。服务器位于我的内部无线网络中,外部无法访问。

我的奇怪行为:

  1. 即使我的移动设备上未启动 Wi-Fi,客户端应用程序中的 connect() 也会返回成功(!= SOCKET_ERROR),但情况并非如此,因为服务器只能在无线网络中访问.

  2. 如果我的移动设备上未启动 Wi-Fi,如果 connect() 和 send() 之间存在 Sleep (1000),则 send() 会失败并显示 WSAECONNRESET,但如果没有 Sleep()在 connect() 和 send() 之间,send() 成功! (只有在执行 read() 时,我才最终得到 WSAECONNRESET 错误)。

非常可怕的是,在实际上无法到达服务器的情况下,我仍然可以成功连接()和发送()

根据要求,这里是示例代码:

#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. 没有睡眠():
main   [INFO   ]  SUCCESS. connected to 192.168.1.105:3100.

main   [INFO   ]  send() SUCCESS
  1. 睡眠():
main   [INFO   ]  SUCCESS. connected to 192.168.1.105:3100.

main   [ERROR  ]  error 10054 sending data to proxy

所以问题是:

  1. 为什么connect()会成功?我如何确定确实存在真正的联系?

  2. 为什么send()会成功?

  3. 为什么在 connect() 和 send() 之间使用 Sleep() 时行为会有所不同?


问题似乎出在 ActiveSync 上。如果 ActiveSync 正在运行,我会得到上述行为(connect() 和 send() 报告成功,即使它们没有成功)。如果 ActiveSync 未运行,gethostbyname() 会失败并显示:

  • WSAENETDOWN -> 如果 Wi-Fi 被禁用

  • WSAHOST_NOT_FOUND -> 如果 Wi-Fi 已启用

哪个是正确的!

怎么会这样呢? ActiveSync 正在做什么,会毁掉一切?我怎样才能避免这个问题?我的意思是,当没有运行 ActiveSync 时,我无法确定用户是否正在运行我的应用程序,那么当 ActiveSync 运行时我可以做什么来避免这种行为?

sockets wifi windows-mobile send
1个回答
0
投票

看起来你至少误用了

struct sockaddr_in
。尝试使用更现代的 API 进行地址转换 - Windows 有
InetPton
- 看看是否可以解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.