Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / September 2006

Tip: Looking for answers? Try searching our database.

writing strings to sockets-- formatting gotchas?

Thread view: 
Jim Bancroft - 09 Sep 2006 22:11 GMT
I'm writing out an integer to a socket using java.  The client on the other
end is a plane-jane C program, and I'm having trouble figuring out why the
two of them won't talk properly.

I'm writing my integer using a DataOutputStream, like so:

String myString = Integer.toString(myInt);
DataOutputStrea, outp;

//....
outp.writeBytes(myString);

in the C client I'm doing this:

n = read(sockfd,mybuf,sizeof(mybuf));

...where mybuf is an unsigned char[16];

when it comes time to print the value I do this:

int newInt;
newInt = atoi(mybuf);

printf("the value is: %d\n", newInt);

But what happens is I get double values on the output.  For instance, if the
java program has a value of "34" in myInt, the printf statement prints out
"3434".  Same with every other integer I try.

I've looked at the mybuf array byte by byte and in fact, there are two
copies of my integer in there.  Does anyone know what might be going on here
and what steps I can take to get C and Java to talk nice in this instance?
Knute Johnson - 09 Sep 2006 22:25 GMT
> I'm writing out an integer to a socket using java.  The client on the other
> end is a plane-jane C program, and I'm having trouble figuring out why the
[quoted text clipped - 28 lines]
> copies of my integer in there.  Does anyone know what might be going on here
> and what steps I can take to get C and Java to talk nice in this instance?

How about writing some test code that shows the problem so we can see
what you are really doing and try it ourselves?  That said, my best
guess is that there is something wrong with your C string termination.

Signature

Knute Johnson
email s/nospam/knute/

Robert M. Gary - 09 Sep 2006 23:13 GMT
In the C code make sure that you either initialize the entire array to
0 (memset) or set the end to null. You may be reading crap off the end
of the buffer. The buffer you pass to atoi MUST have a proper null
terminator. (Alien language to Java guys ;) )

mybuf[n] = '\0';

-Robert

> I'm writing out an integer to a socket using java.  The client on the other
> end is a plane-jane C program, and I'm having trouble figuring out why the
[quoted text clipped - 28 lines]
> copies of my integer in there.  Does anyone know what might be going on here
> and what steps I can take to get C and Java to talk nice in this instance?
Matt Humphrey - 10 Sep 2006 01:34 GMT
> I'm writing out an integer to a socket using java.  The client on the
> other end is a plane-jane C program, and I'm having trouble figuring out
[quoted text clipped - 7 lines]
> //....
> outp.writeBytes(myString);

You need to be aware of what encoding is being used for the String as its
Unicode can be translated into bytes in different ways and may not
necessarily be ASCII or whatever your C program expects.
http://mindprod.com/jgloss/encoding.html

Also, how will the reader know how many bytes to read?  The bytes you are
writing are not null-terminated and do not have implicit length--TCP is not
packet-oriented.  Either set the length to something (like your reader is
doing), send a terminator or send a length-byte first, something like:

//Caution -- Untested code

buffer [] stringBytes = myString.getBytes ("UTF-8");
outp.writeByte (stringBytes.length); // Strings upto 255 chars
outp.writeBytes (stringBytes);

> in the C client I'm doing this:
>
> n = read(sockfd,mybuf,sizeof(mybuf));
>
> ...where mybuf is an unsigned char[16];

There really aren't any guarantees that the n you receive here is the same
as the number of bytes you write. On any single read you could get fewer or
more characters than you wrote on the corresponding write (depending on the
size of the data and whether there's any more, etc.)

Robert's recommendation is definately true, but you must still consider your
protocol as a whole because you may be reading garbage.  Once you've read
the correct amount of data you can put the null terminator into the C
String.

// For reading

n = read (sockfd, mybuf, 1);
int len = (int)mybuf[0];
// len must be <= sizeof(mybuf) // use len to allocate the string area if
you like
// Reading must iterate (not shown here) until the amount read equals the
length
n = read (sockfd, mybuf, len);

// Insert the null terminator yourself
mybuf [len] = '\0';

Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Robert M. Gary - 10 Sep 2006 16:44 GMT
> There really aren't any guarantees that the n you receive here is the same
> as the number of bytes you write. On any single read you could get fewer or
> more characters than you wrote on the corresponding write (depending on the
> size of the data and whether there's any more, etc.)

That's true. For some reason I had assumed a web style TCP where he
would close the socket after the single packet, but that's likely not
realistic. Since our core product is UNIX and our newest stuff is Java
(often PC) I often write this type of code. Usually, I'll start all of
my packets with a header. The first byte is a version number (since its
a *&$# to change protocols with a large existing customer base),
followed by a length of the entire packet, and some other header info.
The first read is the header read (reading the exact, fixed size of the
header), the second read is a blocking read for the length of the
packet based on the header.
This works well for connection-oriented TCP because if either side
were to drop off, the other side would know. This would not work with
UDP because its connectionless and the remote could drop off, restart,
and you would not know that you needed to reset and send a new header
(ie. the two could get out of sync).

-Robert


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.