I'm writing an application for the Symbol 1740 that sends a UDP
multicast to a specific port (906), to which multiple servers respond
by sending responses to port 903 on the handheld.  The application on
the 1740 has a socket set up to listen on port 903.  My application
uses the Berkeley sockets macros and the Palm OS NetLib for network
communication.

The problem I'm having right now is that when more than one server
responds to the handheld, I get the following error right when the
accept() call occurs:

   NetStack1.c, Line:2333, overflowed accept queue

This error does not occur when there is only one server responding to
the UDP multicast; with only one response, the handheld application
accepts the incoming connection and everything is fine.  When I've got
more than one server responding at a time, however, the error above
happens.  The error as written above occurs on a 1740 running Palm OS
3.2; I get the same eror with a different line number (2345) when
running on a 1740 with Palm OS 3.5.2.

I've used listen() to set the queue length for incoming connections to
1; according to the Palm OS SDK Reference, the queue length argument
to NetLibSocketListen (which the listen() Berkeley macro calls) "is
currently quietly limited to 1 (higher values are ignored)" anyhow, so
it shouldn't matter that I'm explicitly setting it to 1.  So, if I'm
reading the docs correctly, there shouldn't be a problem with more
than one incoming connection attempt; there can be only one.  The net
stack on the handheld should grab the first pending connection it
finds when accept() is called.  Unfortunately, there seems to be some
kind of logjam going on here.

Has anyone had any similar problems coding NetLib applications, on
either a Symbol 1740 or a different Palm OS device?  Or can anyone
from Palm let me know if this should be possible at all?  I'm about to
submit this as a bug to Symbol, Palm, or both, because I haven't found
any problems at all in the code I'm using to accept incoming
connections; it's pretty standard Berkeley sockets stuff.

I've included the relevant code from my sample app that reproduces
this problem.  Just so you can follow the code more easily, the
PrintToField() function is a simple routine that prints text to a field
control on the form, and the DiscoverBroadcast() function sets up the
UDP multicast and sends it.  The NetLib reference has already been
found in the application's AppStart() routine.


/|\ Lonnon Foster  <[EMAIL PROTECTED]>  http://pobox.com/~tribble
\|/   When people cease to complain, they cease to think.
/|\                                             -- Arabic Proverb


---begin sample code---

static void MainFormBegin (void)
{
    Err    error;
    UInt16  ifErrs;
    int    returnVal;
    int    listenSock;
    int    responseSock;
    struct linger sLinger;
    struct sockaddr_in  listenSockAddr;      // socket structure - listener socket
    struct sockaddr_in  responseSockAddr;    // socket structure - peer response socket
    int    responseLength;
    Char   *discPacket;
    int    flags = 0;


    // Start up NetLib.
    error = NetLibOpen(AppNetRefnum, &ifErrs);
    if (ifErrs || error){
        if (error != netErrAlreadyOpen)
        {
            if (ifErrs)
                NetLibClose(AppNetRefnum,true);
            StrPrintF(errText, "  Couldn't open NetLib. Error: %d\n", error);
            PrintToField(errText);
            return;
        }
    }

    // Create listen socket.
    PrintToField("  Creating listen socket...\n");
    listenSock = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSock < 0)
    {
        StrPrintF(errText, "    Failed to create listen socket. Error: %d\n", errno);
        PrintToField(errText);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    PrintToField("  Listen socket created.\n");

    // Set linger on listen socket so socket is released immediately
    instead of hanging about.
    sLinger.l_onoff = 0;
    sLinger.l_linger = 0;
    PrintToField("  Setting linger...\n");
    returnVal = setsockopt(listenSock, SOL_SOCKET, SO_LINGER, (char *)
    &sLinger, sizeof(sLinger));
    if (returnVal < 0)
    {
        StrPrintF(errText, "    Failed to set linger on listen socket.  Error: %d\n", 
errno);
        PrintToField(errText);
        close(listenSock);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    PrintToField("  Linger set.\n");

    // Set listener to any IP, port 903.
    MemSet(&listenSockAddr, sizeof(listenSockAddr), 0);         // clear socket 
structure (listen)
    listenSockAddr.sin_family = AF_INET;                // set family to AF_NET
    listenSockAddr.sin_addr.s_addr = htonl(INADDR_ANY); // set IP to 0.0.0.0
    listenSockAddr.sin_port = htons(903);               // set listen port to 903

    // Bind listener to port 903.
    PrintToField("  Binding listener to port 903...\n");
    returnVal = bind(listenSock, (struct sockaddr *)&listenSockAddr,
    sizeof(listenSockAddr));
    if (returnVal < 0)
    {
        StrPrintF(errText, "    Failed to bind listener.  Error: %d\n", errno);
        PrintToField(errText);
        close(listenSock);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    PrintToField("  Listener bound.\n");

    // Set listener to listen.
    PrintToField("  Setting listen for one response...\n");
    returnVal = listen(listenSock, 1);
    if (returnVal < 0)
    {
        StrPrintF(errText, "    Failed to set listener.  Error: %d\n", errno);
        PrintToField(errText);
        close(listenSock);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    PrintToField("  Listener set.\n");

    // Create packet to send.
    discPacket = MemPtrNew(64);
    MemSet(discPacket, MemPtrSize(discPacket), 0);
    StrPrintF(discPacket, "%c%c%cD%c%c%c%c%c", 2, 3, 3, 253, '*', 253, '1', 23);
    discPacket[1] = (char)((StrLen(discPacket) - 4) & 0xff);

    PrintToField("  Broadcasting discovery packet...\n");
    if (DiscoverBroadcast(discPacket) < 0)
    {
        // error
        close(listenSock);
        PrintToField("    Can't create broadcast socket.\n");
        MemPtrFree(discPacket);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    MemPtrFree(discPacket);
    PrintToField("  Discover packet broadcast.\n");

    MemSet(&responseSockAddr, sizeof(responseSockAddr), 0);
    responseLength = sizeof(responseSockAddr);
    PrintToField("  Accepting response...\n");
    responseSock = accept(listenSock, (struct sockaddr *)
    &responseSockAddr, &responseLength);
    if (responseSock < 0)
    {
        if (errno == netErrTimeout)
            StrPrintF(errText, "    Accept timed out\n");
        else
            StrPrintF(errText, "    Failed to accept.  Error: %d\n", errno);
        PrintToField(errText);
        close(listenSock);
        NetLibClose(AppNetRefnum,true);
        return;
    }
    PrintToField("  Response accepted.\n");

    // Close listen socket.
    close(listenSock);

    // Close response socket.
    close(responseSock);

    // Shut down the network library.
    NetLibClose(AppNetRefnum,true);
}



-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/tech/support/forums/

Reply via email to