Freigeben über


"Socket Unknown Error" on Windows Mobile

Have you ever got a "Socket Unknown Error" on Windows Mobile 5.0 and 6 devices, while the exact same code worked with no issues on Windows Mobile 2003? Well, it took some time to understand where the problem lied so I think this post may add some value. Basically we understood that WM5.0 and 6 require that AddressFamily is specified when creating a new socket, because since WM5 both IPv4 and IPv6 are supported. So, the following managed code worked with WM2003, but returned the unspecified "Socket Unknown Error":

 Socket clientSocket = new Socket(AddressFamily.Unspecified, SocketType.Stream, ProtocolType.Tcp);

The same happened with native code, so the problem was not with NETCF's Socket class:

 #include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <winsock2.h>

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData;
    SOCKET conn_socket = INVALID_SOCKET;
    int retval = 0;

    // Load Winsock
    if ((retval = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
    {
        fprintf(stderr,"WSAStartup failed with error %d\n",retval);
        WSACleanup();
        return -1;
    }

    //test conn   
    //Socket clientSocket = new Socket(AddressFamily.Unspecified, SocketType.Stream, ProtocolType.Tcp);
    conn_socket = socket(0, SOCK_STREAM, IPPROTO_TCP);
    if (conn_socket == INVALID_SOCKET)
    {
        fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
        //goto cleanup; //...
    }

    return 0;
}

 

As I said the point is that since WM5 there is IPv4 and IPv6 and you have to specify which version the socket should be created for: for IPv4 you should use AF_INET as the address family specification while for IPv6 you should use AF_INET6. Therefore, specifying the address family resolved it:

 Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Native:

 //IPPROTO_TCP is documented for backward compatibility with Winsock 1.1. 
//SOCK_STREAM always uses TCP for the Internet address family
conn_socket = socket(AF_INET, SOCK_STREAM, 0);