Как использовать переменные, которые создаются внутри одной функции внутри другой функции?F # - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь сделать так, чтобы мой сервер / клиентский чат больше походил на 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...