tags:

views:

55

answers:

1

I have some socket code that works on my Linux box but FAILS on my PowerPC box.

The code (when working on the Linux box) receives a data from a client and then sends the data back to the client. When tested with two netcat applications - the data is successfully wrapped around.

PROBLEM: When tested on a PowerPC (running VxWorks), the echoed data is never received by the client ... (netcat and wireshark show nothing).

On the PowerPC, the server successfully RECEIVES the data (from an x86 client) and claims it successfully ECHOED it back ... but NO DATA is received on the client (netcat on an x86) ... me thinks I may have committed some ENDIAN foobar somewhere. Here is the code snippet as exists on the PowerPC. With two x86 Linux boxes the code works fine ...

while(1) 
{
    readlen = recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *) &client_address, &slen);

    if (readlen == ERROR)
    {
        printf("RECVFROM FAILED()/n");
        return (ERROR);
    }

    printf("Received %d bytes FROM %s:%d\nData: %s\n\n", 
           readlen, inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port), buf);

    // Send it to right back to the client using the open UDP socket
    // but send it to OUTPORT
    client_address.sin_port = htons(OUTPORT);
    sendlen = sendto(sock, buf, BUFLEN, 0, (struct sockaddr *)&client_address, slen);


// more code ....
}

Maybe I need to htons the client address too? ...

A: 

I don't think endianness is a problem in the code you've shown, and on a big-endian PowerPC htons() etc. are no-ops anyway (network order is big-endian)!

I'm suspicious of your use of slen in the recvfrom() call. It is an in-out parameter to recvfrom(), which should be passed in as the maximum size of the address buffer, and contains the actual size of the address you got on return.

If the initial value of slen (before the loop that you've shown) is too small, the address stored in client_address by recvfrom() will be truncated.

So slen should be set to sizeof(client_address) just before calling recvfrom(). (Also you should ensure that slen is declared with a type of the correct size - POSIX uses socklen_t for this.)

Matthew Slattery
I cannot be `sizeof(...)` in `recvfrom()` because it needs to be read/write. I think the usage of `slen` is correct here. Have you tested the return value from `sendto()`? Perhaps it will have a descriptive error code.
Jonathan
Also, make sure to reset `slen` before the `recvfrom()` call. I only meant that the usage in the `sendto()` call was correct.
Jonathan
@Jonathan: I think you misread my original answer. When I said "it should be set ... before calling `recvfrom()`", I was suggesting setting `slen`, not passing `sizeof(...)` as the parameter (which would clearly be incorrect). I have edited to clarify, and to explain why I think the code as given in the question can go wrong.
Matthew Slattery
@Matthew Good edit, much clearer now.
Jonathan
Xofo