Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

use of readLine versus read, reading from a socket, with C on the other end  RSS feed

 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I need to read data, being passed into the socket, from a C application.
The data comes in as a string, but does not seem to be null terminated.
It does NOT have a carriage return at the end.

if I use readline it just freezes waiting for what I believe is a carriage return.

Using read (not readline) I am not sure how to detect the end of the message.

Currently the data is being read via another C program, and it somehow knows how to detect the end of the message.
It is not looking for a specific character, it is not looking for a specific number of bytes.
It just knows, and then returns the number of bytes sent.
(maybe the other side is disconnecting after sending the message?, I can not think of any other way, it can know, that the message has ended.)
I have no visibility into the code on the other side.

Can someone point me to a good example, of a socket read, that does character by character, and then knows when to stop reading characters, based on the other side disconnecting?
Or maybe even suggest another way to do this?

Thank you

 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok,

checking for -1 is the answer.

Anyway,
I am still interested in links to good examples using read, or alternatives to reading one character at a time, for strings which do not end in a carriage return.

Thanks.
 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now I am confused again.

In the case of my server, it needs to continually listen.
It also needs to write a response.

On the other side, I suspect it waits for the response, before closing.
Therefore it can not be indicating end of stream, by closing the socket.

So how does a socket, recognize end of stream?
Is C much different then Java here?

I found a very similar question in another forum, but it would require I sign up to see the answer (and this particular forum has such a messy tedious sign up process, that the first time I attempted it, I quit about half way through.)
http://www.experts-exchange.com/Programming/Languages/Java/Q_20762865.html

Maybe someone does have a membership in that forum, and can look at that answer.

[note: I do have a socket solution working, where I use jni, and the old C code that was previously handling my end of this socket. This way I can pass the strings from java to the socket, and back again. But this is so very messy, that I really want to replace it with clean java socket code.]
 
Joe Ess
Bartender
Posts: 9428
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
eileen keeney wrote:
Using read (not readline) I am not sure how to detect the end of the message.


Using readLine() with sockets is a Bad Idea. The EOL character is platform-dependent, so even if the other end were sending one, there's no guarantee that they'd send the "right" one for your platform. See here.
Reading a stream until one gets -1 is perfectly valid, the -1 character being the end-of-stream character in Java.
 
Tim Holloway
Bartender
Posts: 18705
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are 2 types of connections used with servers: continuous and intermittent. Continuous is better for true MVC architectures, since MVC requires that the server be able to post to the client without advance notice or solicitation.

However, the popular HTTP protocol is an intermittent one. The client opens a connection, sends a request, gets a response. Connections are closed with each request/response cycle. That's why even the most MVC-like of J2EE architectures is only MVC-like and not true MVC.

Setting up connections is relatively expensive, so modern-day HTTP servers cheat a little and use a "keep-alive" mechanism, but the underlying protocol is still intermittent.

A continuous connection, on the other hand, is like a terminal or printer connection. There's no true "End of File", because there's always more data than can come later - think of the way a remote login terminal works. The connection is just the transport. So it's up to the client and server to agree on what delineates data units, and part of that agreement is to define what makes up a data unit. Usually that means that you prefix the stream with a length indicating the amount of data to follow, or you include some sort of sentinel to indicate EOF. MS-DOS used "Ctrl-Z" originally, since the first-generation filesystem allocated fixed-size sectors and a text file needed a way to indicate that the rest of the sector wasn't used. IBM mainframes tend to be partial to "/*", and "999EOF" or variant are always popular, too.

readline isn't all that dangerous in Java. It's true that EOL characters vary by OS - and Apple is one of the biggest offenders, since their original terminator wasn't NL (a/k/a LF), it was CR. However, the readline and println methods normalize a lot of that. Part of that is because Java is expected to provide "Write Once/Run Anywhere" capabilities to text-handling programs and part of it is the general Internet slant of complete neutrality relating to text. IBM mainframes were a big part of the beginning of the Internet, so a lot of the protocols are not only text-based (including HTTP and MAIL), they are expected to endure code page translations - mainframes are EBCDIC machines, and even have a different binary value for the NL character unless my senility deceives me. Certainly most of the control character values are different.

Java addresses these problems by providing mechanisms to normalize into Unicode. Sometimes a little care is required to be truly portable (assuming you even need portable), but some of us quite cheerfully do mainframe/DOS/Unix universal string processing all day long. Well, mostly cheerfully.
 
eileen keeney
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ok so
IF I do NOT need platform independence (as I don't since the rest of the existing app is not at all platform independent anyway)
AND
I control both sides of the socket, readln seems like the best solution to me.

However, I am not lucky enough to control both sides of this particular connection, nor am I lucky enough to see the code on the side I am talking to.
Nor do I have a test system for the system I am talking to, so testing time is very limited.




 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!