我试图使我的服务器/客户端聊天更像一个p2p应用,其中一个使用开始作为主机,另一个使用连接,然后成为主机,原始主机也作为客户端连接到他。但是我无法使用connectedStream
中tryListen()
中的receive()
之类的变量。如果我不得不猜测这是不可能的,那么我必须以某种方式进行重组,但我想以防万一。完整代码如下。
open System
open System.Net
open System.Net.Sockets
open System.Text
open System.Threading
printf "Connect from IP: "; let connectFromIP = Console.ReadLine() |> IPAddress.Parse;;
printf "Connect from Port: "; let connectFromPort = Console.ReadLine() |> int;;
printf "Connect to IP: "; let connectToIP = Console.ReadLine();;
printf "Connect to Port: "; let connectToPort = Console.ReadLine() |> int;;
let buffer: byte[] = Array.zeroCreate 256
let rec tryListen() =
try
let tcpListener = new TcpListener(connectFromIP, connectFromPort)
tcpListener.Start()
printfn "Waiting for Client."
let connectedClient = tcpListener.AcceptTcpClient()
let connectedStream = connectedClient.GetStream()
printfn "Client connected."
with
| _ ->
printfn "Retrying..."
Thread.Sleep(1000)
tryListen()
let rec tryConnect() =
try
let tcpClient = new TcpClient(connectToIP, connectToPort)
let clientStream = tcpClient.GetStream()
printfn "Connected to Server."
with
| _ ->
printfn "Retrying..."
Thread.Sleep(1000)
tryConnect()
printfn "Listen or Connect first? (L/C)"; let choice = Console.ReadLine();;
match choice with
| "L" | "l" -> tryListen()
| "C" | "c" -> tryConnect()
| _ -> ()
let rec chat() =
let receive() = async {
let connectStreamReader = connectedStream.Read(buffer, 0, buffer.Length)
let data = Encoding.ASCII.GetString(buffer, 0, connectStreamReader)
printfn "Received: %s" data
connectedStream.Flush()
chat()
}
let send() = async {
printfn "Message: "
let message: byte[] = Encoding.ASCII.GetBytes(Console.ReadLine())
clientStream.Write(message, 0, message.Length)
clientStream.Flush()
send() |> ignore
}
[ receive(); send() ]
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
chat()