[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: TCP Socket Programming
On Wed, 6 Sep 2000, 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 whichbasis 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?
Probably Nagle (take a look at RFC 896 'the small packet problem'). Try
to disable Nagle on the senders (not sure this is possible). BTW, anyone
who have seen '[A' while typing an Up Arrow withing vi has stumbled upon
Nagle (actually, a combination of Nagle and vi's low timeout value).
> 2. Any suggested "fix"?
What are the clients ?
>
> 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).
-- Yaron.
=================================================================
To unsubscribe, send mail to linux-il-request@linux.org.il with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail linux-il-request@linux.org.il