Skip to content

Instantly share code, notes, and snippets.

@panesofglass
Forked from t0yv0/AsyncSockets.fs
Created June 25, 2012 21:52
Show Gist options
  • Save panesofglass/2991544 to your computer and use it in GitHub Desktop.
Save panesofglass/2991544 to your computer and use it in GitHub Desktop.
Asynchronous socket programming with F# async.
open System.Net.Sockets
type A = System.Net.Sockets.SocketAsyncEventArgs
type B = System.ArraySegment<byte>
exception SocketIssue of SocketError with
override this.ToString() =
string this.Data0
/// Wraps the Socket.xxxAsync logic into F# async logic.
let inline asyncDo (op: A -> bool) (prepare: A -> unit)
(select: A -> 'T) =
Async.FromContinuations <| fun (ok, error, _) ->
let args = new A()
prepare args
let k (args: A) =
match args.SocketError with
| System.Net.Sockets.SocketError.Success ->
let result = select args
args.Dispose()
ok result
| e ->
args.Dispose()
error (SocketIssue e)
args.add_Completed(System.EventHandler<_>(fun _ -> k))
if not (op args) then
k args
/// Prepares the arguments by setting the buffer.
let inline setBuffer (buf: B) (args: A) =
args.SetBuffer(buf.Array, buf.Offset, buf.Count)
let Accept (socket: Socket) =
asyncDo socket.AcceptAsync ignore (fun a -> a.AcceptSocket)
let Receive (socket: Socket) (buf: B) =
asyncDo socket.ReceiveAsync (setBuffer buf)
(fun a -> a.BytesTransferred)
let Send (socket: Socket) (buf: B) =
asyncDo socket.SendAsync (setBuffer buf) ignore
open System.Net.Sockets
/// Thrown when sockets encounter errors.
exception SocketIssue of SocketError
/// Performs AcceptAsync.
val Accept : Socket -> Async<Socket>
/// Performs ReceiveAsync.
val Receive : Socket -> System.ArraySegment<byte> -> Async<int>
/// Performs SendAsync.
val Send : Socket -> System.ArraySegment<byte> -> Async<unit>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment