Comments (6)
I think to start with we should document the current behavior. I'm worried that behavior in Network.Socket.recv
and Network.Socket.ByteString.recv
differs here. Secondly we should take a deep look to see what the POSIX standard specifies here and consider if we ought to change our current behavior. We shouldn't make such a decision lightly, given the age and widespread use of the API.
On a more philosophical note I don't like the Haskell way of handling EOF by throwing an exception. EOF is not an error condition.
from network.
Secondly we should take a deep look to see what the POSIX standard specifies here and consider if we ought to change our current behavior.
The recv
system call returns 0 on EOF, consistent with the documentation of Network.Socket.recv.
On a more philosophical note I don't like the Haskell way of handling EOF by throwing an exception. EOF is not an error condition.
The hGetBufSome function doesn't throw an exception. It returns empty strings on EOF, like the recv
system call does. getLine
and getChar
, however, do throw EOF when there are no more lines or characters, which makes more sense.
I strongly feel that the current implementation of Network.Socket.recv is incorrect in throwing EOF on end of input, but concede that it would break things to change it now. However, the new (and not-yet-released) recvBuf
has the incorrect behavior.
How about this:
- Update the documentation of Network.Socket.recv to describe the current behavior, and encourage users to use the ByteString version instead. Network.Socket.recv is basically deprecated anyway.
- Implement the correct semantics in
recvBuf
. It hasn't been released yet, so this shouldn't break anything.
from network.
Sounds good.
from network.
Houston, we have a problem. recvBufFrom
throws an exception on EOF, and it's been around since 2004. Here are the relevant commits:
- 7b43363 (2002): changes recv, recvFrom to throw an exception on EOF
- b401455 (2004): adds sendBufTo/recvBufFrom
Commit 7b43363 gives this justification:
* Have these map zero-byte results from the underlying
APIs to an EOF IOError, bringing them into line with
what the hGet* actions do when interpreting read()
results.
But what hGet*
actions were they talking about? hGetBuf returns 0 instead of throwing an exception. It has for a long time. However, some other functions do throw EOF:
- getChar throws EOF on end of input, since there's no sane way to return a
Char
on end of input. An exception-free variant would have typeIO (Maybe Char)
. - getLine throws EOF on end of input. If it returned an empty line instead, it would be indistinguishable from empty lines in the file (e.g.
\n\n\n
). An exception-free variant would have typeIO (Maybe String)
.
Here is an argument against recv
functions returning an empty string on EOF: the caller has to give the zero-length string special treatment. If a caller naïvely reads chunks until it has enough data, it will go into an infinite loop.
Perhaps we should add Maybe
variants, so the caller explicitly handles the EOF case:
recvMaybe :: Socket -> Int -> IO (Maybe String)
recvBufMaybe :: Socket -> Ptr Word8 -> Int -> IO (Maybe Int)
recvBufFromMaybe :: Socket -> Ptr a -> Int -> IO (Maybe Int, SockAddr)
These functions will never throw EOF, and will never return Just ""
or Just 0
.
I like this idea a lot:
- Avoids changing the semantics of the existing functions, both of which are older than most dogs
- Eliminates ambiguity regarding EOF
- Callers explicitly handle the EOF case
- Callers don't give 0 special treatment
The Maybe
wrapping/unwrapping should have negligible performance impact. It should be dwarfed by system call overhead, which is on the order of microseconds.
So what do we do about ByteString.recv
versus Socket.recv
? Also, how should the new recvBuf
behave?
from network.
So what do we do about ByteString.recv versus Socket.recv ? Also, how should the new recvBuf behave?
I don't think we should expand the String
API any more. We'd like people to stop using it eventually. Lets just document its behavior. As for recvBuf
, I think we should be consistent and raise an exception on EOF.
As a separate issue we could look into what kind of changes would be needed to go from an old crufty API to a more modern one that's easier to use. This likely needs some thought/discussion.
from network.
Network
module is deprecated. So, I close this.
from network.
Related Issues (20)
- Failed to build network-3.1.2.7 with ghc-8.10 on Linux HOT 1
- Will not build without msghdr.msg_control HOT 3
- Incorrect handling of `address` argument in recvfrom() HOT 10
- Sending data and file descriptors at the same time HOT 7
- SendTimeOut/RecvTimeOut
- Problems building with network dependency on Windows (GHC 9.6.1/Cabal 3.10.1.0) HOT 12
- Document how to close sockets in a threaded scenario HOT 7
- Support GHCs 9.4 and 9.6 in CI HOT 1
- Emulating socketPair on Windows HOT 7
- Don't declare `_GNU_SOURCE` on Windows HOT 1
- v4.0 HOT 4
- Deprecation warnings with bytestring-0.11.5; allow bytestring-0.12 HOT 3
- Bug: ControlMessage Fd should be ControlMessage [Fd] (SCM_RIGHTS can contain > 1 Fd) HOT 1
- Accept may leak file descriptor when thrown an asynchronous exception HOT 6
- Exception when setting `UserTimeout` with `setSocketOption` HOT 1
- Replacement for old `connectTo` HOT 1
- Build failure on Windows (CI broken) HOT 1
- Empty SCC annotations makes profiling tools fail HOT 2
- What should I write instead of `isBound`? HOT 3
- Configure: Error: cannot run config.sub HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from network.