Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com From: Corinna Vinschen Date: Fri, 8 Dec 2000 13:28:57 +0100 X-Mailer: KMail [version 1.1.99] Content-Type: text/plain; charset="iso-8859-1" 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> Content-Transfer-Encoding: 8bit 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