so just get the fourth (fifth, actualy) of Stevens: Unix socket programing
.
Dani
On Thu, 7 Sep 2000, Daniel Feiglin wrote:
> 1. It's not Nagle
>
> 2. Keren is right - Mostly. I did take care to have my client flush its output
>buffer after each write, so the server
> should have picked the same number of reads. After sending off my original query, I
>went for a long walk, and hit on the
> answer, which I just finished implementing. It's this:
>
> The listener thread, upon registering a client in the user table, allows the mux
>read thread to start collecting data.
> Despite the flush, and despite my pacing the client messages 1/2 a second apart, the
>header and the first few records
> get picked up. I grab the header and open the output file. All subsequent stuff goes
>to the output log file - apart from
> the first few entries. The oddball thing, is thereafter there is no apparent
>buffering of client data.
>
> The solution is quite simple: Have the Java client do a (blocking) read (of say, one
>byte) on the socket after sending
> the header. Have the server sent a single "sync" byte to the client immediately
>after opening the log file. And all
> works just fine.
>
> Apropos of reading a good book on TCP "kishkes" - I have Steven's 3 "Protocol"
>volumes: You need a year's
> sabbatical from work to read them ...
>
> I suppose that the moral of the story, is to prepare a query to the list, take a
>walk, and then send it to the trash
> basket. Just the exercise of formulating a problem like this for someone else to
>read often carries its solution ...
>
> Thanks for the replies.
>
>
>
> Daniel Feiglin wrote:
> >
> > This programming problebm is not specific to Linux; it can be reproduced under
>Unix (e.g Solaris).
> >
> > Here is the scenario: I have a C++ server (a sort of logger, a bit like syslog)
>and many Java clients.
> >
> > Each Java client sends the server a text header record which I'll describe in a
>moment, and thereafter, user generated
> > text "log" records. Every client write() (using the output stream obtained from
>the socket), is followed by a flush()
> > call, to ensure that each write() is indeed carried out.
> >
> > The header record, a comma delimited list, contains a file name, where I want the
>server to throw out the subseqent
> > stuff on a per client basis. It contains other fields not pertinent to this query.
> >
> > The server is built in "classic" fashion: A listener thread, assigns each client a
>file descriptor, and a multiplexed
> > read thread (using select())
> > processes reads from the clients. I use standard pthreads (Write once, run many).
> >
> > When a Java client comes "on board", it first sends the header, upon which basis a
>log file is opened by the server on
> > the client's behalf. All subsequent message from that client are recognized as log
>messages and written to the client's
> > log file.
> >
> > When a client disconnects, the server detects it (as a zero length read buffer)
>and cleanly closes the file and the
> > socket connection.
> >
> > I maintain a table of online client records, which uses standard pthread mutexes
>to avoid a few simple potential
> > clashes.
> >
> > Now for the problem:
> >
> > When a client comes up, for some reason or other, the header and the first first
>few log records are aggregated by TCP,
> > and appear on select() as a single read(). All subsequent client writes are picked
>up correctly. I can vary the number
> > of initially aggregated records by reducing the select() timeout (but not setting
>it to zero!). The worst results are
> > obtained, when I allow select() to block.
> >
> > If for example, I set the select() timeout to say, 1 sec and force the client to
>sleep 2 secs after issueing the header,
> > I can make the problem "disappear", if for an obvious reason.
> >
> > 1. Why does TCP aggregate the first few records, and then "settle down" and behave
>as expected?
> >
> > 2. Any suggested "fix"?
> >
> > If it is felt that this is somewhat off-topic, please reply directly to me.
> >
> > References: Stevens, UNP Vol 1, and APUE, syslog sources (for an example).
=================================================================
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]