Re: reading ints from a socket

From: Jon A. Cruz (jon_at_joncruz.org)
Date: 03/14/04


Date: Sat, 13 Mar 2004 16:45:04 -0800

Stu Mac wrote:
> Hi there
>
> I have a ServerSocket in a java program and i connect to it using a
> client socket written in C. The two sockets accept each other fine
> but I have a wierd problem when trying to send a int across the
> socket;

Ok. First question would be "how are you writing that in C"? That is
very important.

You're not just pointing to a variable and shoving bytes out like this:
int i = 8;
write( fd, &i, sizeof(i) );

and for reading:
read( fd, &i, sizeof(i) );

In general that's a VERY bad C/C++ approach, is fragile and will break
whenever anyone sneezes. Unfortunately, that's what's going on far too
often.

>
> In java i'm trying:
>
> out.print(0); // that's int zero, not capital o
>
> where "out" is a printwriter from the socket.getOutputStream.

Ahh. There's one big problem. Writers use characters in Java. In Java,
characters are 16-bit unsigned Unicode integers. In C/C++ characters are
usually 8-bit signed or unsigned characters. So in C/C++ things will
often be written out directly, but Writers in Java will be doing some
lossy conversion from Unicode to an unknown character encoding.

> I'm trying to read this into c using lines similar to:
>
> int var1
> int buf[2];
>
> read(fd, buf, 1);
>
> var1 = buf[0]

Eeeeek! Scary.

You need to get things settled out. First of all, read() deals with
bytes. ints can be 16-bit, 32-bit or 64-bit, etc, depending on the
platform.

When dealing with network or file IO you should think only in "bytes".
(Or if you're thinking like RFC's, call them "octets").

The next question is.... what do you mean by "int"? 16-bit? 32-bit? You
need to be explicit with things. Let's assume you mean "32-bit integer".
That means you'd be expecting to read and write 4 bytes for each integer.

First, let's fix that implicit conversion (the function takes a pointer
to what it is going to treat as bytes, but you gave it the address of an
int).

int var1;
char buf[4];
read(fd, buf, 4);

var1 = ????;

Hmmm... but that's not quite so clear. Lets switch to the standard
explicit types:

int32_t var1;
uint8_t buf[4];
read(fd, buff, 4 );
var1 = ????;

Ahhh. Better.

But now how do we get from bytes to ints? We know that 4 bytes are
needed, but what about putting those back togeter?

Well, which byte order do you want to use over the network? I'd
personally go with network byte order. In that case, this will do the trick:

var1 = (buf[0] << 24)
       |(buf[1] << 16)
       |(buf[2] << 8)
       |(buf[3] << 0);

There you go. That should make things clearer and easier to understand
exactly what's going on.

int32_t var1;
uint8_t buf[4];
read( fd, buff, 4 );
var1 = (buf[0] << 24)
       |(buf[1] << 16)
       |(buf[2] << 8)
       |(buf[3] << 0);

There are some other ways to do that, but that C code will compile and
execute the same on just about any platform out there. Well, at least on
all the common platforms in use today.

Oh, and for Java, just remember that unlike C it only has signed bytes,
so mask with 0x0ff before shifting. (And for Java-specific followups,
trim comp.lang.c before you post)



Relevant Pages

  • Re: how to wait for socket communications
    ... the JVM when the Java program gets closed, and ending up with memory leaks. ... to use socket communication between my C++ program and my Java program. ... int sockfd; ...
    (microsoft.public.win32.programmer.networks)
  • Re: reading ints from a socket
    ... > client socket written in C. ... > but I have a wierd problem when trying to send a int across the ... > In java i'm trying: ... Writers use characters in Java. ...
    (comp.lang.c)
  • Re: how to wait for socket communications
    ... actually at this point I am ready to try out your file I/O suggestion. ... the JVM when the Java program gets closed, and ending up with memory leaks. ... to use socket communication between my C++ program and my Java program. ... int sockfd; ...
    (microsoft.public.win32.programmer.networks)
  • Re: Explanation needed of binary operators
    ... I am trying to read an int from a file written in binary. ... binary data as an "archaic" file structure. ... int in Java but don't understand what is happening. ... Big-endian hardware stores bytes in memory in their "natural" format, ...
    (comp.lang.java.programmer)
  • Re: Is anything easier to do in java than in lisp?
    ... In Linj you write: ... > argumentList in java. ... > int String.indexOf ... (position c str:from-end t) ...
    (comp.lang.lisp)