Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0

    Question client/server, error receving integers


    Hello
    I have C++ client and java sever and the server send integers to the client but the data recevied by the client in the reverse byte order, i don't really understand what it does by reversing and all
    The code is like this:

    // receive some ints, returns num of ints received

    int Client::recv_ints(int *val, int maxlen)
    {
    int numbytes = 0;
    int i, j;
    char *temp;
    char *result;
    int end = 0;
    int total_bytes = 0;

    temp = (char *) buffer;
    result = (char *) buffer2;

    j = 0;

    // we receiving the incoming ints one byte at a time
    // cross language sockets

    while (!end)
    {
    if ((numbytes=recv(new_fd, temp, BUFFSIZE, 0))==-1)
    perror("recv");
    for (i=0; i<numbytes; i++)
    {
    result[j] = temp[i];
    j++;
    }

    total_bytes = total_bytes + numbytes;
    if (total_bytes==maxlen*sizeof(int))
    end = 1;
    }

    // now we need to put the array of bytes into the array of ints

    char *ptr;
    int num = j/sizeof(int);

    ptr = (char *) val;

    // the significance order depends on the platform

    if (REVERSE)
    {
    // we need to reverse the order of each set of bytes
    for (i = 0; i < num; i++)
    {
    for (j=0; j<sizeof(int); j++)
    ptr[i*sizeof(int)+j] = (char)
    result[(i+1)*sizeof(int)-j-1];
    }
    }
    else
    {
    // leave the byte order as is
    for (i = 0; i < j; i++)
    {
    ptr[i] = result[i];
    }
    }

    if (VERBOSE)
    {
    printf("Server: received %d ints - ", num);
    for (i=0; i<num; i++)
    printf("%d ", val[i]);
    printf("\n");
    }

    send_ack();
    recv_ack();

    return num;
    };

    Can somebody please explaing what it really does, and what it means by reversing the byte order, becoz the values which i see on the output i just cannot understand them , how does it reverse it?

    Please help

    Max
  2. #2
  3. ASP.Net MVP
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Aug 2003
    Location
    WI
    Posts
    4,378
    Rep Power
    1511
    Some machines (ie, linux and windows) have integers in different orders (little vs big endian). It's been a while, but I think it was the htons and ntohs (host to network before a send, network to host on receive, both sending shorts) functions.
    Primary Forum: .Net Development
    Holy cow, I'm now an ASP.Net MVP!

    [Moving to ASP.Net] | [.Net Dos and Don't for VB6 Programmers]

    http://twitter.com/jcoehoorn
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0
    Hello
    How should i use htons for it

    My output is like this:

    when i send from java server integers
    0 1 4 9 16 25 36 49 64 81

    the C++ client receives like this (in reversed byte order)
    0 16777216 67108864 150994944 268435456 419430400 and so on

    I cannot interpret this results,

    Max
  6. #4
  7. ASP.Net MVP
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Aug 2003
    Location
    WI
    Posts
    4,378
    Rep Power
    1511
    Like I said, it's been a while since I've done any socket coding. You'll have to check a reference manual somewhere, or maybe someone else will reply.
    Primary Forum: .Net Development
    Holy cow, I'm now an ASP.Net MVP!

    [Moving to ASP.Net] | [.Net Dos and Don't for VB6 Programmers]

    http://twitter.com/jcoehoorn
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0
    Thanx for your info,
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,174
    Rep Power
    2222
    As you already know, different platforms can have different byte order. However, in TCP/IP everything going out over the network must be in network byte-order. Read my web-page section on this at http://members.aol.com/dsc30574/sock...tml#BYTE_ORDER .

    The Sockets API provides four functions for converting short and long integers from host order to network order and from network order to host order. It does this without your needing to know what your own platform's byte order is. These four functions are (from my page):
    unsigned short htons(unsigned short hostshort);
    "host to network, short", for converting a two-byte integer from host order to network order

    unsigned long htonl(unsigned long hostlong);
    "host to network, long", for converting a four-byte integer from host order to network order

    unsigned short ntohs(unsigned short netshort);
    "network to host, short", for converting a two-byte integer from network order to host order

    unsigned long ntohl(unsigned long netlong);
    "network to host, long", for converting a four-byte integer from network order to host order
    Basically, you need to use a hton* function when preparing the packet you are going to send. Then you need to use a ntoh* function to extract that data from the packet you received.

    Example:
    In my timserver server and client, I send and receive the long int containing the time thus:
    Code:
    // Server:
        *((unsigned long*)(&sendString[0])) = htonl(GetTime(sTime));
    
    // Client:
        ulTime = ntohl(*((unsigned long*)(&buffer[0])));
    Ist's klar jetzt?
  12. #7
  13. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0
    Thanx for the info
  14. #8
  15. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0
    Das ist vollkommen, danke zu der Information
  16. #9
  17. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,174
    Rep Power
    2222
    Das machte ich gern. Glad to have helped.

    There are a few other issues you need to be aware of concerning the format of your packet's data.

    It can be tempting to write an entire struct in one operation, but data alignment as well as byte order can cause problems. In order to make memory access easier, short ints will normally be aligned on even address boundaries and long ints on address boundaries divisible by 4. This means that within a struct, extra bytes will be inserted between fields in order to align them.

    If the hosts that the server and client are running on employ different alignment, this can cause another real mess. I encountered something very similar with a binary file I created under Windows and tried to read under Linux. Although the struct was declared identically (actually, it was the exact same program compiled first under Windows and then again under Linux), the struct size was different and caused me a lot of trouble.

    The general solution for sending a struct's data would be to define an explicit format for the packet data, then move each data field from the struct to the packet data format. Of course, the packet data format would also have to define byte order; it should follow the rule of using network byte order. For an example, I recommend that you look at RFC 2030 for the definition of the Network Time Protocol (NTP) packet data format -- search on Google for RFC 2030.
  18. #10
  19. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    You may want to simply convert the structure into formatted ASCII and convert back at the other end. In my opinion you will wind up with MUCH more readable, debuggable and maintainable code. However, if you are sending something like a gif or jpeg which is encoded bytewise, then there is no need to jump through those hoops, only if it is binary data representing values larger than a byte. Keep in mind that unless you are sending more than a few K bytes, the overhead associated with connection establishment, packet sending (most packets have a payload of > 1K), recieving, connection teardown is so high that any conversion/deconversion to ASCII will not be a significant fraction of the comunication.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  20. #11
  21. It Doesn't Work!
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Slovenia
    Posts
    112
    Rep Power
    12
    If you don't know how do do something, you know where to search, I hope.

    Is that right, dwise?:)
  22. #12
  23. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0

    Arrow


    Hello and thanx to all
    The data which i need to tansfer from server to client is only integers from 1000 to - 1000 as my input for the controliing of a device.
    What should be considered in mind for doing only this.

    Thanx again
    Max
  24. #13
  25. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0

    Exclamation


    hello again
    Actually my send and recv funnctions are like this, and like i said previously i only need to send interger values from 1000 to -1000.


    My C++ (Client) recv function is this:

    int Client::recv_ints(int *val, int maxlen)
    {
    int numbytes = 0;
    int i, j;
    char *temp;
    char *result;
    int end = 0;
    int total_bytes = 0;

    temp = (char *) buffer;
    result = (char *) buffer2;

    j = 0;

    // receiving the incoming ints one byte at a time

    while (!end)
    {
    if ((numbytes=recv(new_fd, temp, BUFFSIZE, 0))==-1)
    perror("recv");
    for (i=0; i<numbytes; i++)
    {
    result[j] = temp[i];
    j++;
    }

    total_bytes = total_bytes + numbytes;
    if (total_bytes==maxlen*sizeof(int))
    end = 1;
    }

    // now we need to put the array of bytes into the array of ints

    char *ptr;
    int num = j/sizeof(int);

    ptr = (char *) val;

    // the significance order depends on the platform

    if (REVERSE)
    {
    // we need to reverse the order of each set of bytes
    for (i = 0; i < num; i++)
    {
    for (j=0; j<sizeof(int); j++)
    ptr[i*sizeof(int)+j] = (char)
    result[(i+1)*sizeof(int)-j-1];
    }
    }
    else
    {
    // leave the byte order as is
    for (i = 0; i < j; i++)
    {
    ptr[i] = result[i];
    }
    }

    if (VERBOSE)
    {
    printf("Server: received %d ints - ", num);
    for (i=0; i<num; i++)
    printf("%d ", val[i]);
    printf("\n");
    }

    send_ack();
    recv_ack();

    return num;
    };




    And the java (server) send inte method is like this:

    public void send_ints(int vals[], int len) throws IOException
    {
    if (VERBOSE) System.out.print("Client: sending " + len +" ints: ");

    /* convert our array of ints into an array of bytes */

    ByteArrayOutputStream bytestream;
    bytestream = new ByteArrayOutputStream(len*INT_SIZE);

    DataOutputStream out;
    out = new DataOutputStream(bytestream);

    for (int i=0; i<len; i++)
    {
    out.writeInt(vals[i]);
    if (VERBOSE) System.out.print(vals[i]+" ");
    }

    byte byte_array[] = bytestream.toByteArray();

    if (reverse)
    {
    // flip around our bytes if necessary

    byte flip_array[] = new byte[bytestream.size()];
    int i, j;

    for (i=0; i<len; i++)
    {
    for (j=0; j<INT_SIZE; j++)
    {
    flip_array[(i+1) * INT_SIZE - j - 1] =
    byte_array[i * INT_SIZE + j];
    }
    }

    output.write(flip_array, 0, bytestream.size());
    }
    else
    output.write(byte_array, 0, bytestream.size());

    output.flush();

    if (VERBOSE) System.out.println("");

    recv_ack();
    send_ack();
    }


    Now as i said
    when i send from java server integers
    0 1 4 9 16 25 36 49 64 81

    the C++ client receives like this (in reversed byte order)
    0 16777216 67108864 150994944 268435456 419430400 and so on

    the C++ gets it is hexadec format in reversed byte order, now i have to use ntohl to get the same no's as i send, is it right. And now i do i use it in my code.

    Thanx,
    Max
    Last edited by Max_2003; August 25th, 2003 at 05:45 AM.
  26. #14
  27. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Location
    Germany
    Posts
    29
    Rep Power
    0
    hey all
    help me out in it, i am struck with this byte reversal stuff, I am not able get the desired result in right format on my client/server

    HELP

    Max
  28. #15
  29. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    hi it seems from a first look that you are doing some unneccessary things. i dont understand why you are attempting to recieve one byte at a time. why not try to recieve one integer at a time instead. like this,
    Code:
    recvfrom(sock, buf, sizeof(int), NULL);
    also, after you recieve the integer you should call the function ntohl, liike this
    Code:
     my_Int = ntohl( * (unsigned int *) (buffer))
    what that does is first casts the buffer to be of type unsigned int *, then it dereferences that location to get the value and convert it to the proper byte order. now keep in mind, if you are going to use ntohl() on the client side, you need to first use htonl() on the server side. You must explicitly put the data in network byte order, and then explicitly take it out of nwbo. hope that helps
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo