Link to home
Start Free TrialLog in
Avatar of Peter Kwan
Peter KwanFlag for Hong Kong

asked on

urgent: Palm OS Emulator and netlib

I want to do the following:

connect -> receive hello from server -> send auth to server -> receive response from server -> send goodbye to server -> disconnect

// connect: ok
NetLibSocketConnect(libRef, socket, (NetSocketAddrType*)&srvAddr, sizeof(srvAddr), SOCKET_TIMEOUT, &err);

// Receive from server: ok
NetLibReceive(libRef, socket, (void*)&inBuf, inBufLen, 0, 0, 0, SOCKET_TIMEOUT, err);

// send something to server: ok (no error)
NetLibSend(libRef, socket, (void*)&outBuf, 7, netIOFlagOutOfBand, 0, 0, SOCKET_TIMEOUT, &err);

// receive from server: netErrSocketClosedByRemote (4628)
NetLibReceive(libRef, socket, (void*)&inBuf, 6, 0, 0, 0, SOCKET_TIMEOUT, err);

For real servers, I get netErrSocketClosedByRemote for the second call of NetLibReceive. It just can be solved by changing the server to localhost (127.0.0.1).

How can I solve this problem? I am using Palm OS Emulator and my PC is connected to internet using broadband (ethernet NIC). I don't have any cradle and modem.

Is there anything that I should set for the emulator and any software needed so that I can make my program work for the real servers (i.e. not 127.0.0.1)?

Thanks.
Avatar of prakash_raj
prakash_raj

Hi,

On your emulator, right click and select Settings-->Properties..

Did you check the Redirect Netlib calls to host TCP/IP checkbox ??

Cheers,
Prakash
Avatar of Peter Kwan

ASKER

Hi Prakash,

I have already checked "Redirect netlib calls to host TCP/IP" checkbox already.

Thanks.
so when your server runs locally and you point it to it, it works?

can you properly ping it from the machine your emulator is running on?
>so when your server runs locally and you point it to it, it works?
yes. only localhost server works. If I changed to other server (real IP but not localhost), it does not work.

>can you properly ping it from the machine your emulator is running on?
the server is up, i can ping the server properly.
When calling NetLibSend you should
specify 0, not netIOFlagOutOfBand
-unless you have a good reason? which one?

If that doesn't solve it...
Are you sure the server receives what you send?
If yes, how are you sure? Are you also
developing the server?


Have you verified, other NetLib-enabled apps work from your emulator and can hit other servers? For example, trying using some Palm Web browser on your emulator to open up www.yahoo.com...

to olan75,

> When calling NetLibSend you should
> specify 0, not netIOFlagOutOfBand
> -unless you have a good reason? which one?

> If that doesn't solve it...
> Are you sure the server receives what you send?
> If yes, how are you sure? Are you also
> developing the server?
chaning to 0 does not solve the problem. i am not developing the server.

to schang:
i have tried to use web browser and can goto websites, say www.icq.com.
Are you saying that when the server is running
on your local machine, it works, but not
when the server is running on a remote machine?
All other things being equal?

You really need to provide more info:

What kind of server is it? What does it do?

Do you have access to the remote machine, or
are you just connecting to some machine on the net?

Is is the exact same server software (version, etc)
that is running on your local machine and on the remote?

Are you sure you're connecting to the right port number?
What port number is it?
Are you behind a firewall?

Apparently the server does not like what you sent and it
shuts down the connection.

Could you post more code:
What did you receive the first time?
How do you check what you receive?
How do you initialize your send buffer?
Please include variable declarations and
tests that are done to check return values
of your network calls.
>Are you saying that when the server is running
>on your local machine, it works, but not
>when the server is running on a remote machine?
>All other things being equal?
I downloaded a freeware (but not open source) program from
the net and tried to connect to ICQ server through the program using 127.0.0.1 (to track my packet).
For my program, it is ok if I connect to ICQ login server through the program, but if I connect to the server using my own program, it fails.

>You really need to provide more info:

>What kind of server is it? What does it do?
ICQ server. (Actually I tried IMAP server, and it does not work through direct connection either.)

>Do you have access to the remote machine, or
>are you just connecting to some machine on the net?
I am just connecting to some machine on the net, I have no admin rights to access it.

>Is is the exact same server software (version, etc)
>that is running on your local machine and on the remote?

>Are you sure you're connecting to the right port number?
Yes. I hard coded it.

>What port number is it?
5190

>Are you behind a firewall?
no.

>Apparently the server does not like what you sent and it
>shuts down the connection.

>Could you post more code:
>What did you receive the first time?
Welcome message. (Correct)

>How do you check what you receive?
There is documentation on the net about the protocol.

>How do you initialize your send buffer?
>Please include variable declarations and
>tests that are done to check return values
>of your network calls.

#define MAX_PACKET_LENGTH 8192
#define SOCKET_TIMEOUT sysTicksPerSecond*5
UInt8 inBuf[8192];      // incoming buffer
UInt8 outBuf[8192];      // outgoing buffer

Err Login(const Char* userUIN, const Char* password) {
      Err error = 0;
      UInt16 netIFError;
      Int16 recvBufLen = 0, sendBufLen = 0, cookieLen = 0;
      UInt8 cookie[MAX_PACKET_LENGTH];
      Char srv2Addr[16];            // second server address: currently not used
      UInt16 i;
      UInt16 prefSize, uinLen = StrLen(userUIN);

      // Open the library      
      error  = NetLibOpen(libRefNum, &netIFError);
      if (error && error != netErrAlreadyOpen)
            return ShowError("NetLibOpen", error);
      if (netIFError)
            return ShowError("NetLibOpen", netIFError);
      
      // Open the sockets
      socket1 = NetLibSocketOpen(libRefNum, netSocketAddrINET, netSocketTypeStream, NULL, SOCKET_TIMEOUT, &error);
      if (error == -1)
            return ShowError("NetLibSocketOpen", error);

      socket2 = NetLibSocketOpen(libRefNum, netSocketAddrINET, netSocketTypeStream, NULL, SOCKET_TIMEOUT, &error);
      if (error == -1)
            return ShowError("NetLibSocketOpen", error);
      
      // Connect to server 1
//      error = Connect(socket1, DEB_SERVER, ICQ_PORT);            // debug
      error = Connect(socket1, ICQ_SERVER, ICQ_PORT);            // real
      if (error)
            return error;      
      
      // receive SRV_HELLO from server 1
      if ((recvBufLen = RecvPacket(socket1, "1: Receive SRV_HELLO", &error)) < 0)
            return error;
      
      // send CLI_IDENT to server 1
      sendBufLen = FlapIdent(userUIN, password);
      if (NetLibSend(libRefNum, socket1, (void*)&outBuf, sendBufLen, 0, 0, 0, SOCKET_TIMEOUT, &error) < 0)
            return ShowError("1: Send CLI_IDENT", error);

      // receive SRV_COOKIE from server 1
      if ((recvBufLen = RecvPacket(socket1, "1: Receive SRV_COOKIE", &error)) < 0)
            return error;
      
      if (inBuf[4 + uinLen] != 0x00 || inBuf[5 + uinLen] != 0x05) {
            // invalid
            if (inBuf[4 + uinLen] == 0x00 && inBuf[5 + uinLen] == 0x08)
                  ShowError("Too many connections. Please try again later", 10001);
            else
                  FrmAlert(alertLoginFail);
            
            // Disconnect
           if (NetLibSocketShutdown(libRefNum, socket1, netSocketDirBoth, SOCKET_TIMEOUT, &error))
                return ShowError("NetLibSocketShutdown", error);
   
          if (NetLibSocketClose(libRefNum, socket1, SOCKET_TIMEOUT, &error) < 0)
                return ShowError("NetLibSocketClose", error);
                  
            return 1;
      }
      
      // Other codes not relevant

      return error;
}

// show the error
Err ShowError(const Char* desc, const Err error) {
      Char errCode[10];
      StrPrintF(errCode, "%u", error);
      FrmCustomAlert(alertError, desc, errCode, NULL);      
      return error;             
}

/* Byte string copying */
void ByteStrCopy(UInt8* dest, const UInt8* src, const UInt16 start, const UInt16 len) {
      UInt16 i;      
      for (i = 0; i < len; i++)
         dest[i] = src[start + i];
}

// receive packets
Int16 RecvPacket(NetSocketRef socket, const Char* desc, Err* error) {
      Int16 inBufferLen = 0, inBufLen = 0, retBufLen = 0;

      MemSet(inBuf, MAX_PACKET_LENGTH * sizeof(UInt8), '\0');
      // Header
      if ((inBufLen = NetLibReceive(libRefNum, socket, (void*)&inBuf, 6, 0, 0, 0, SOCKET_TIMEOUT, error)) < 0) {
            ShowError(desc, *error);
            return -1;
      }
      retBufLen = (UInt16)inBuf[4] * 256 + (UInt16)inBuf[5] + 6;  
      inBufferLen = retBufLen - 6;
      
      while (inBufferLen > 0) {
            MemSet(inBuf, MAX_PACKET_LENGTH * sizeof(UInt8), '\0');
            if (inBufferLen >= MAX_PACKET_LENGTH - 1) {
                  if ((inBufLen = NetLibReceive(libRefNum, socket, (void*)&inBuf, MAX_PACKET_LENGTH - 1, 0, 0, 0, SOCKET_TIMEOUT, error)) < 0) {
                        ShowError(desc, *error);
                        return -1;
                  }
                  inBufferLen = inBufferLen - inBufLen;
            }
            else {
                  if ((inBufLen = NetLibReceive(libRefNum, socket, (void*)&inBuf, inBufferLen, 0, 0, 0, SOCKET_TIMEOUT, error)) < 0) {
                        ShowError(desc, *error);
                        return -1;
                  }                  
                  inBufferLen = 0;
            }      
      }
      
      return retBufLen;
}

=================================


ASKER CERTIFIED SOLUTION
Avatar of olan75
olan75

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks anyway.

One more question, can I configure in the Palm emulator settings so that I can see what is being sent to the server using NetLibSend? If yes, how to do it?

Thanks.
Not that I know of.
You can use a winsock sniffer.
Or, you can use PalmReporter and the HostTraceOutputB function to trace what you're sending/receiving.
I have had success with both methods in the past.

Although the OP provided no feedback, the methods suggested should have helped him solve his problem (they did require him to do more work).
Thanks