5 people like it.
Like the snippet!
tcpStream abstraction
Basic (but experimental) TCP stream wrappers to help make TCP more abstracted and cleaner. Giving the user just the impression of a 'stream' that one connects to and sends and receives.
This helps promote composition. The first abstraction is 'stream', really just wrapping .NET stream functions so that read returns the read n bytes and write returns the stream, all functions take NetworkStream as the first parameters, followed by other parameters.
Currently we don't care about timeouts, exceptions, or other nasty's.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
|
open System.Net
open System.Text
open System.Net.Sockets
module stream =
type stream = NetworkStream
let curry g b n = g(b,0,n) |> ignore; b
let read (s : stream) n = curry s.Read (Array.zeroCreate n) n
let write (s : stream) b = curry s.Write b b.Length; s
let close (s : stream) b = s.Close(); b
let connect host port = TcpClient(host,port).GetStream()
(* example *)
let sendString host (data : string) =
stream.connect host 80
|> fun stm ->
data
|> Encoding.Default.GetBytes
|> stream.write stm
|> stream.read <| 256
|> Encoding.Default.GetString
|> stream.close stm
let data = "GET / HTTP/1.1\r\nHost: microsoft.com\r\n\r\n"
// not robust for all server types, just for demo, no exceptions.
let getServerHeader (s : string) =
let needle = s.IndexOf "Server: "
s.[needle..needle+24]
sendString "microsoft.com" data |> getServerHeader
(* val it : string = "Server: Microsoft-IIS/7.5" *)
|
namespace System
namespace System.Net
namespace System.Text
namespace System.Net.Sockets
type stream = NetworkStream
Full name: Script.stream.stream
Multiple items
type NetworkStream =
inherit Stream
new : socket:Socket -> NetworkStream + 3 overloads
member BeginRead : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
member BeginWrite : buffer:byte[] * offset:int * size:int * callback:AsyncCallback * state:obj -> IAsyncResult
member CanRead : bool
member CanSeek : bool
member CanTimeout : bool
member CanWrite : bool
member Close : timeout:int -> unit
member DataAvailable : bool
member EndRead : asyncResult:IAsyncResult -> int
...
Full name: System.Net.Sockets.NetworkStream
--------------------
NetworkStream(socket: Socket) : unit
NetworkStream(socket: Socket, ownsSocket: bool) : unit
NetworkStream(socket: Socket, access: System.IO.FileAccess) : unit
NetworkStream(socket: Socket, access: System.IO.FileAccess, ownsSocket: bool) : unit
val curry : g:('a * int * 'b -> 'c) -> b:'a -> n:'b -> 'a
Full name: Script.stream.curry
val g : ('a * int * 'b -> 'c)
val b : 'a
val n : 'b
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
val read : s:stream -> n:int -> byte []
Full name: Script.stream.read
val s : stream
val n : int
NetworkStream.Read(buffer: byte [], offset: int, size: int) : int
module Array
from Microsoft.FSharp.Collections
val zeroCreate : count:int -> 'T []
Full name: Microsoft.FSharp.Collections.Array.zeroCreate
val write : s:stream -> b:byte [] -> stream
Full name: Script.stream.write
val b : byte []
NetworkStream.Write(buffer: byte [], offset: int, size: int) : unit
property System.Array.Length: int
val close : s:stream -> b:'a -> 'a
Full name: Script.stream.close
System.IO.Stream.Close() : unit
NetworkStream.Close(timeout: int) : unit
val connect : host:string -> port:int -> NetworkStream
Full name: Script.stream.connect
val host : string
val port : int
Multiple items
type TcpClient =
new : unit -> TcpClient + 3 overloads
member Available : int
member BeginConnect : host:string * port:int * requestCallback:AsyncCallback * state:obj -> IAsyncResult + 2 overloads
member Client : Socket with get, set
member Close : unit -> unit
member Connect : remoteEP:IPEndPoint -> unit + 3 overloads
member Connected : bool
member EndConnect : asyncResult:IAsyncResult -> unit
member ExclusiveAddressUse : bool with get, set
member GetStream : unit -> NetworkStream
...
Full name: System.Net.Sockets.TcpClient
--------------------
TcpClient() : unit
TcpClient(localEP: IPEndPoint) : unit
TcpClient(family: AddressFamily) : unit
TcpClient(hostname: string, port: int) : unit
val sendString : host:string -> data:string -> string
Full name: Script.sendString
val data : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
module stream
from Script
val stm : NetworkStream
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Encoding.Default: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val write : s:stream.stream -> b:byte [] -> stream.stream
Full name: Script.stream.write
val read : s:stream.stream -> n:int -> byte []
Full name: Script.stream.read
Encoding.GetString(bytes: byte []) : string
Encoding.GetString(bytes: byte [], index: int, count: int) : string
val close : s:stream.stream -> b:'a -> 'a
Full name: Script.stream.close
val data : string
Full name: Script.data
val getServerHeader : s:string -> string
Full name: Script.getServerHeader
val s : string
val needle : int
System.String.IndexOf(value: string) : int
System.String.IndexOf(value: char) : int
System.String.IndexOf(value: string, comparisonType: System.StringComparison) : int
System.String.IndexOf(value: string, startIndex: int) : int
System.String.IndexOf(value: char, startIndex: int) : int
System.String.IndexOf(value: string, startIndex: int, comparisonType: System.StringComparison) : int
System.String.IndexOf(value: string, startIndex: int, count: int) : int
System.String.IndexOf(value: char, startIndex: int, count: int) : int
System.String.IndexOf(value: string, startIndex: int, count: int, comparisonType: System.StringComparison) : int
More information