# linear-socket | linear-socket | 0.3.3.3 | | ------------- | --------------------------------- | | Maintainer | Allele Dev (allele.dev@gmail.com) | | Funding | $0 USD | | Copyright | Copyright (C) 2017 Allele Dev | | License | GPL-3 | ## Overview A networking socket library aiming to add tracking of socket properties at the type level. Currently, the following are tracked: * socket status: unconnected, open, bound, etc * socket family: inet4, inet6, unix * socket protocol: tcp, udp * socket shutdown state: available, can't send, can't receive, etc This makes it so that many socket programming errors are caught before the program is ever run. For example: * sending or receiving from a TCP socket that isn't connected * can still `sendTo`/`recvFrom` for UDP sockets * listening on a socket that hasn't been bound * accepting from a socket that hasn't started listening * sending from a socket that has had it's send capability `shutdown` * receiving from a socket that has had it's recv capability `shutdown` However, the protection isn't perfect. In particular, until linear types are used, the following is one way to cause errors in lieu of the type protection: 1. Create a thread taking a socket and modify the socket in the parent view: ``` haskell sock <- tcp4Socket bound <- bind serverAddress sock server <- listen 1 bound forkIO (doThing server) close server doThings :: SSocket f p s sh -> IO () doThings server = do accept server -- this will crash because of the close above ``` ## Examples Imports: ``` haskell import Network.Typed.Socket import Network.Socket (tupleToHostAddress) ``` Setting a TCP/IPv4 server address: ``` haskell serverAddress = SockAddrInet 2291 (tupleToHostAddress (127,0,0,1)) ``` An echo server: ```haskell -- point-free style pfServer = tcp4Socket >>= bind serverAddress >>= listen 1 >>= (\server -> accept server >>= (\(client, _) -> recv 32 client >>= (\bs -> send bs client))) -- explicit do-notation doServer = do sock <- tcp4Socket bound <- bind serverAddress sock server <- listen 1 bound (client, _) <- accept server bs <- recv 32 client send bs client ``` An echo client: ``` haskell -- point-free style pfClient = tcp4Socket >>= connect serverAddress >>= (\client -> send "fish" client >> recv 32 client) -- explicit do-notation doClient = do sock <- tcp4Socket client <- connect serverAddress sock send "fish" client recv 32 client ``` ## Contributing Contributions are welcome! Documentation, examples, code, and feedback - they all help. Be sure to review the included code of conduct. This project adheres to the [Contributor's Covenant](http://contributor-covenant.org/). By participating in this project you agree to abide by its terms. This project currently has no funding, so it is maintained strictly on the basis of its use to me. No guarantees are made about attention to issues or contributions, or timeliness thereof. ## Developer Setup The easiest way to start contributing is to install [stack](https://github.com/commercialhaskell/stack). stack can install GHC/Haskell for you, and automates common developer tasks. The key commands are: * `stack setup`: install GHC * `stack build`: build the project * `stack clean`: clean build artifacts * `stack haddock`: builds documentation * `stack test`: run all tests * `stack bench`: run all benchmarks * `stack ghci`: start a REPL instance ## Licensing This project is distributed under the GPL-3 license. See the included [LICENSE](./LICENSE) file for more details.