Click here to Skip to main content
15,867,330 members
Articles / Mobile Apps / Windows Mobile

Power up the TCP/IP capability in your PocketPC application

Rate me:
Please Sign up or sign in to vote.
4.71/5 (17 votes)
19 Dec 2002CPOL3 min read 184.1K   321   55   37
Establish a TCP/IP connection to other applications.

Introduction

Everyone should have an idea on accessing Winsock in eMbedded Visual Basic 3.0. Its 100% easy and straight forward as what I did in Visual Basic. But how about eMbedded Visual C++ 3.0?

The Winsock for MS Windows CE does not support WSAAsyncSelect. Hence, we need to write a chunk of code as well as the synchronization thread to handle the incoming and outgoing data ourselves.

Using the code

The posted code is the entire sample project. So you might need to cut & paste the following function in order to utilize the piece of code in your own project. Don't worry, the code is easy to identify and all you need is to filter out all my demo project GUI interface control code.

Below are the three basic functions and the two synchronization threads you need to copy:

// Function
int  InitSocket (HWND); // Initialize the Winsock.DLL
void  OpenSocket (HWND); // Open the server side socket
void  CloseSocket(HWND); // Close the server side socket

// Synchronization Thread

// Waiting for the incoming connection request
DWORD WINAPI StartListen (LPVOID pParam); 
// Reading the incoming buffer
DWORD WINAPI ReadInBuffer (LPVOID pParam); 

Once you have copied the code, you need to call the above mentioned three functions in sequence. As each of them is to perform a specific task. Em... Lets look at the first function InitSocket as below. Basically, all it does is just initialize the Winsock component (version 1.1) by calling the WSAStartup API before we can proceed to create/use any socket.

WSADATA wsaData;

// Initliatize the Winsock dll version 1.1
if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0)
{
    // Fail to initialize the winsock dll
    MessageBox(hWnd, TEXT("Fail to initialize the Winsock DLL!"), 
                       TEXT("MySocket"), MB_OK | MB_ICONEXCLAMATION);
    // Set the return value
    return 1;
}
else
    // Successful initialize the Winsock DLL
    // Set the return value
    return 0;

Second, we need to create a new socket to listen to an incoming request (connect to a host) on a specific port number and accept the connection request (establish the connection). But you will notice there is some extra code under the OpenSocket which is used to handle the GUI control for determining whether the socket going to be created is in Server mode or Client mode. This is because both will have two different logic flow and characteristics.

Hence, if the socket going to be created is in server mode, all you need is proceed to create the synchronization thread (StartListen). Else, you will need to execute the following code to establish a connection to the specific host followed by creating the ReadInBuffer synchronization thread.

NOTE: All the non-relevant GUI code is filtered out in the following display code (but not in the attached demo project code). You may need to add your own GUI control/updated code into this function.

// Reset the SOCKADDR_IN struct
memset(&sckAddress, 0, sizeof(sockaddr_in));
// Setup the sckClient socket
sckClient = socket(AF_INET, SOCK_STREAM, 0);
sckAddress.sin_port = htons(atoi(port));
sckAddress.sin_family = AF_INET;
sckAddress.sin_addr.s_addr = inet_addr(host);
if(connect(sckClient, (struct sockaddr *)&sckAddress, 
                     sizeof(sckAddress)) != SOCKET_ERROR)
// Create read input buffer thread
    hThread2 = CreateThread(NULL, 0, ReadInBuffer, hWnd, 0, &dwThreadID);
else
    // Notify user about the error
    MessageBox(hWnd, TEXT("Client~Fail to establish the connection!"), 
                          TEXT("MySocket"), MB_OK | MB_ICONEXCLAMATION);

What is inside the StartListen synchronization thread? When you look into the code, you'll find that it is an infinite do...while loop in this thread and perform a checking on the socket state on every loop until it gets a valid socket handle as show in the code below:

if(sckServer != INVALID_SOCKET)
{
    // Setup the port number, protocol & etc..
    sckAddress.sin_port = htons(atoi(port));
    sckAddress.sin_family= AF_INET;
    sckAddress.sin_addr.s_addr = INADDR_ANY;
    // Bind the socket
    bind(sckServer, (struct sockaddr *)&sckAddress, sizeof(sckAddress));

    // Listen to the specific port for 1 client connection only
    listen(sckServer, 1);

    // Start looping and check the respective port for incoming request
    do
    {
        // Socket callback status structure
        fds;
        // Maximum wait time for the "select" command
        tv.tv_sec = 1;
        tv.tv_usec = 1; 
        // Initialize the fd_set structure to NULL
        FD_ZERO (&fds);
        // Add the sckServer socket to fd_set structure
        FD_SET (sckServer, &fds);
        // Call the select command
        if (select(0, &fds, NULL, NULL, &tv) == 0)
            // Maximum wait time is expired.
            continue;
        // Check is there any incoming request/active in the fd_set structure
        // Zero mean no, else
        if (FD_ISSET(sckServer, &fds) != 0)
        {
            // Accept the incoming request
            sckClient = accept(sckServer, NULL, 0);
            // Close the existing listen socket (sckServer)
            closesocket(sckServer);
            // Reset the sckSocket variable to NULL
            sckServer = INVALID_SOCKET;
            // Update status control
            SetDlgItemText(hWnd, IDC_STATUS1, TEXT("Connected"));
            // Create read input buffer thread
            hThread2 = CreateThread(NULL, 0, ReadInBuffer, 
                                        hWnd, 0, &dwThreadID);
            // Self terminate this thread
            break;
        }
    }while (sckServer != INVALID_SOCKET);
}
else
    // Notify user about the error
    MessageBox(hWnd, TEXT("Server~Fail to open the socket!"), 
                  TEXT("MySocket"), MB_OK | MB_ICONEXCLAMATION);

At this stage, you still can not receive any data from the host (client) connection. So, the ReadInBuffer synchronization thread is heard of the entire demo application which enables you to receive any data from host (client) connection.

Hence, lets take a look on the ReadInBuffer coding and understand more about its operation.

HWND hWnd = NULL;
char *Buff=NULL;
TCHAR *wBuff=NULL;

int err;

// map the pass in variable
hWnd = (HWND)pParam;
// Create new string buffer
wBuff = new TCHAR[1024];
Buff = new char[1024];

if (sckClient != INVALID_SOCKET )
{
    // Loop until no data in the input buffer
    while (true)
    {
        // Reset the allocated string buffer
        memset(wBuff, TEXT('\0'), 1024*sizeof(TCHAR));
        memset(Buff, '\0', 1024);
        // Read the data from valid socket
        err = recv(sckClient, Buff, 1024, 0);
        if (err == SOCKET_ERROR || err <= 0)
        {
            // Remote terminal reset the socket connection
            CloseSocket(hWnd);
            // Self terminate the thread
            break;
        }
        else
        {
            // Convert from MultiByte to UNICODE
            mbstowcs(wBuff, Buff, 1024);
            // Display the received data
            SetDlgItemText(hWnd, IDC_EDIT3, wBuff);
        }
    }
}

// Release the used memory
delete Buff;
// Self terminate the thread
ExitThread(WM_QUIT);
// Set the return value
return 0;

From the above code, there is an infinite while loop which will constantly check the socket status and it will break the looping when there is an invalid socket detected.

Last, we must destroy the socket when not in use or upon detecting the host (client) connection is lost. Therefore, the CloseSocket function is straight forward as shown below.

// Validate
if(sckServer != INVALID_SOCKET)
{
    // Close the current server side socket
    if (closesocket(sckServer) == 0)
    // Reset the sckServer
        sckServer = INVALID_SOCKET;
    else
        // Notify user about the error
        MessageBox(hWnd, TEXT("Server~Fail to close the socket."), 
                        TEXT("MySocket"), MB_OK | MB_ICONEXCLAMATION);
}

P.S If you need to get the local machine IP address, all you need is call the GetLocalIP function as included in the demo application.

Will do.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Australia Australia
Passion to be a software architect and solution researcher in enterprise solutions by simplify and unify the existing complex manual paper works into an automated environment friendly, comprehensive and dynamic workflow process system.

Comments and Discussions

 
QuestionHow can I download files from internet to my ppc [modified] Pin
enderchen26-Aug-07 20:39
enderchen26-Aug-07 20:39 
GeneralSame but don't woek Pin
Bandoleiro15-Jun-07 5:18
Bandoleiro15-Jun-07 5:18 
QuestionLink Error Pin
Allan Yan1-Mar-07 18:05
Allan Yan1-Mar-07 18:05 
AnswerRe: Link Error Pin
Allan Yan1-Mar-07 20:33
Allan Yan1-Mar-07 20:33 
QuestionNo connection to Internet by Pocket PC 2003 Emulator Pin
Csharper200613-Jul-06 10:40
Csharper200613-Jul-06 10:40 
QuestionActiveSync and establish second connection? Pin
Eugen Wiebe1-Jun-06 4:34
Eugen Wiebe1-Jun-06 4:34 
QuestionHow to run thIs example program ... Pin
22-Oct-05 0:43
suss22-Oct-05 0:43 
AnswerRe: How to run thIs example program ... Pin
dt.lcr29-Mar-06 15:28
dt.lcr29-Mar-06 15:28 
AnswerRe: How to run thIs example program ... Pin
vijasi29-Mar-06 17:40
vijasi29-Mar-06 17:40 
QuestionGPRS? Pin
Donovan Hutcheon8-Sep-05 22:19
sussDonovan Hutcheon8-Sep-05 22:19 
QuestionGPRS? Pin
Donovan Hutcheon8-Sep-05 22:19
sussDonovan Hutcheon8-Sep-05 22:19 
AnswerRe: GPRS? Pin
Tili30-Oct-05 17:58
Tili30-Oct-05 17:58 
GeneralWince Message Queues Opening Problem Pin
indianstar21-Jun-05 0:22
indianstar21-Jun-05 0:22 
GeneralGetting Linking Error Pin
indianstar9-Jun-05 2:51
indianstar9-Jun-05 2:51 
GeneralRe: Getting Linking Error Pin
CT CHANG9-Jun-05 14:49
CT CHANG9-Jun-05 14:49 
GeneralRe: Getting Linking Error Pin
indianstar9-Jun-05 18:56
indianstar9-Jun-05 18:56 
GeneralRe: Getting Linking Error Pin
CT CHANG12-Jun-05 17:52
CT CHANG12-Jun-05 17:52 
GeneralQuestion Pin
Hing29-Mar-04 19:00
Hing29-Mar-04 19:00 
GeneraleVC 4.0 Pin
trajecto11-Nov-03 18:56
trajecto11-Nov-03 18:56 
GeneralRe: eVC 4.0 Pin
CT CHANG25-Dec-03 0:35
CT CHANG25-Dec-03 0:35 
GeneralRe: eVC 4.0 Pin
jundar18-Jan-05 1:23
jundar18-Jan-05 1:23 
GeneralFTP connection Pin
Simone Sanfilippo15-Oct-03 23:22
Simone Sanfilippo15-Oct-03 23:22 
Hi K-Pax,
I have a great problem with Ftp protocol on my Pocket Pc 2002. I need transfer file from a server ftp to my pocket pc and viceversa. I used whit insuccessiful a class of FTP Client publicated on CodeGuru site. That class return an error when I use a GetFile member function. I read your article and download your code, but in my pocket pc I can't set the ip number of server ftp ... can I set this ip? Or no?

Thanks
QuestionHow can I use TCP/IP for transfer file Pin
Simone197629-May-03 23:33
Simone197629-May-03 23:33 
AnswerRe: How can I use TCP/IP for transfer file Pin
CT CHANG30-May-03 0:28
CT CHANG30-May-03 0:28 
GeneralRe: How can I use TCP/IP for transfer file Pin
Simone197630-May-03 0:48
Simone197630-May-03 0:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.