delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2000/12/08/07:29:30

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
From: Corinna Vinschen <cygwin AT cygwin DOT com>
Date: Fri, 8 Dec 2000 13:28:57 +0100
X-Mailer: KMail [version 1.1.99]
To: cygwin AT cygwin DOT com
References: <1529f1887b DOT 1887b1529f AT uth DOT tmc DOT edu>
In-Reply-To: <1529f1887b.1887b1529f@uth.tmc.edu>
Subject: Re: socket read()/write() problem in 1.1.6
MIME-Version: 1.0
Message-Id: <00120813285702.12851@cygbert>
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id HAA06658

On Friday 08 December 2000 06:57, Markus Hoenicka wrote:
> With cygwin1.dll 1.1.4 I get:
> $ ./server5a &
> [1] 1003
>
> markus AT WUTZ ~/prog/cygnus-b20/socket
> $ server waiting
> ../client3a
> char to server = 123456789
> adding client on fd 4
> server waiting
> serving client on fd 4; ch=123456789<<
> removing client on fd 4; ch=223456789<<
> server waiting
> char from server = 223456789
>
> With 1.1.6 I get:
> $ ./server5a &
> [1] 141
>
> markus AT WUTZ ~/prog/cygnus-b20/socket
> $ server waiting
> ../client3a
> char to server = 123456789
> adding client on fd 4
> server waiting
> serving client on fd 4; ch=123456789<<
> removing client on fd 4; ch=223456789<<
> server waiting
> char from server = 2234500000
>
> i.e. only the first write() gets through.

Ok, I had a chance to look into your sources and to examine what's
going on.

AFAICS, the problem is that you rely on the speed of the connection.
The `read' call on the socket returning only 5 bytes while you're
expecting 10 is doing nothing wrong. Let me explain:

The difference between Cygwin <= 1.1.4 and >= 1.1.5 is that socket
connections are treated as `slow' in the earlier versions while they
are treated as `fast' in the later versions. The implication is that
the earlier versions are doing some overhead on the connection which
results in that the TCP service provider has more time to collect the
incoming information on the socket.

So, when the `read' call in your code is running, the server had
already time to send both 5 bytes packages. In the newer
implementation, the overhead is stripped from the socket `read' call
so the `read' is much faster than before. `read' calls `recv' in turn
and that `recv' call is executed more or less immediately. So, when
the server sends it's 5 byte package, `recv' (which is a Winsock call,
btw) returns that 5 byte package. That's ok!

If you change the client, so that it performs a `sleep(3)' prior to
calling `read', you will see what I mean.

From the description of `recv' in the MSDN:

"For connection-oriented sockets (type SOCK_STREAM for example), calling
recv will return as much information as is currently available - up to
the size of the buffer supplied."

From the Linux `recv' man page:

"The receive calls normally return any data available, up to the
 requested amount, rather than waiting for receipt of the full
 amount requested."

From the Linux `read' man page:

"On success, the number of bytes read is returned (zero indicates
 end of file), and the file position is advanced by this number. It
 is not an error if this number is smaller than the number of bytes
 requested; this may happen for example because fewer bytes are
 actually available right now (maybe because we were close to
 end-of-file, or because we are reading from a pipe, or from a
 terminal), or because read() was interrupted by a signal."

So, your `read' code should not look like this:

  read(sockfd, chin, 10);

but rather look like that (assuming you expect receiving 10 bytes):

  len = 0;
  do {
    i = read(sockfd, chin + len, 10);
  } while (i > 0 && (len += i) < 10);


Hope, that helps,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Developer                                mailto:cygwin AT cygwin DOT com
Red Hat, Inc.
mailto:vinschen AT redhat DOT com

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019