Asynchronous 如何使用F#通过UDP异步接收和发送?
我正在尝试通过UDP创建一个消息传递应用程序,并使其能够同时连续发送和接收消息。我不知道如何做到这一点,并尝试了一些事情。下面是我到目前为止的代码,有人能指出我做错了什么或者我需要补充什么吗?多谢各位Asynchronous 如何使用F#通过UDP异步接收和发送?,asynchronous,f#,udp,Asynchronous,F#,Udp,我正在尝试通过UDP创建一个消息传递应用程序,并使其能够同时连续发送和接收消息。我不知道如何做到这一点,并尝试了一些事情。下面是我到目前为止的代码,有人能指出我做错了什么或者我需要补充什么吗?多谢各位 open System open System.Net open System.Net.Sockets open System.Text printfn "Receive port: " let receivePort = Console.ReadLine() |> int let re
open System
open System.Net
open System.Net.Sockets
open System.Text
printfn "Receive port: "
let receivePort = Console.ReadLine() |> int
let receivingClient = new UdpClient(receivePort)
let ReceivingIpEndPoint = new IPEndPoint(IPAddress.Any, 0)
printfn "Send address: "
let sendAddress = IPAddress.Parse(Console.ReadLine())
printfn "Send port: "
let sendPort = Console.ReadLine() |> int
let sendingClient = new UdpClient()
let sendingIpEndPoint = new IPEndPoint(sendAddress, sendPort)
let rec loop() =
let receive = async {
try
let! receiveResult = receivingClient.ReceiveAsync() |> Async.AwaitTask
let receiveBytes = receiveResult.Buffer
let returnData = Encoding.ASCII.GetString(receiveBytes)
printfn "%s" returnData
with
| error -> printfn "%s" error.Message
}
receive |> ignore
printfn "Send message: "
let (sendBytes: byte array) = Encoding.ASCII.GetBytes(Console.ReadLine())
try
sendingClient.Send(sendBytes, sendBytes.Length, sendingIpEndPoint) |> ignore
with
| error -> printfn "%s" error.Message
loop()
loop()
Console.Read() |> ignore
代码中一个明显的问题是,您创建了一个异步计算
receive
,然后忽略它,而从未启动它。这意味着您当前的版本仅发送
我假设您打算在后台启动接收过程。为此,我们首先将receive
和send
定义为两个独立的异步函数:
let receive () = async {
try
let! receiveResult = receivingClient.ReceiveAsync() |> Async.AwaitTask
let receiveBytes = receiveResult.Buffer
let returnData = Encoding.ASCII.GetString(receiveBytes)
printfn "%s" returnData
with
| error -> printfn "%s" error.Message }
let send () = async {
printfn "Send message: "
let (sendBytes: byte array) = Encoding.ASCII.GetBytes(Console.ReadLine())
try
sendingClient.Send(sendBytes, sendBytes.Length, sendingIpEndPoint) |> ignore
with
| error -> printfn "%s" error.Message }
现在,根据“同时”的确切含义,有不同的发送和接收方式。您可以在后台开始接收,然后同时发送,然后等待发送和接收完成后再循环:
let rec loop() = async {
let! wait = Async.StartChild (receive ())
do! send ()
do! wait
return! loop() }
loop() |> Async.Start
或者,您也可以启动两个循环,一个继续发送,另一个继续尽可能快地接收:
let rec loop1() = async {
do! receive ()
return! loop1() }
let rec loop2() = async {
do! send ()
return! loop2() }
loop1() |> Async.Start
loop2() |> Async.Start
这看起来不错,但当我运行程序两次时,一个在端口1000接收,另一个在端口1001发送,另一个相反,当程序尝试发送消息,但消息从未发送时,程序关闭。知道为什么吗?@Alanay如果您使用的是第一个变体,那么两个程序在发送之前都必须先接收。因此,您可能需要使用第二种方法。除此之外,我没有看到任何明显的问题,但我没有尝试过测试这一点……我尝试了第二种方法,但也有同样的问题,但无论哪种方法都很有用,谢谢。现在我将学习更多关于异步的知识。