gpt4 book ai didi

sockets - UDP 客户端 - 如何在 BeginReceive 之后关闭

转载 作者:行者123 更新时间:2023-12-03 12:03:33 26 4
gpt4 key购买 nike

我需要从我的 ERP 系统(Dynamics Nav)中接收小型 UDP 数据包。我用互联网上的一些代码创建了一个类(我第一次使用 UDP 代码),添加了一个 COM 接口(interface)并在 Nav 中使用生成的 DLL。它立即工作,但我意识到 udp.Close() 函数并没有真正关闭这个东西,我无法再次实例化该类。

在 stackoverflow 和其他网站上查看了许多关于 udp.BeginReceive() 的主题后,我明白了其中的原因。在关闭 upd 对象之前,需要进行最终的 udp.EndReceive 调用。

由于该类在后台运行,因此它使用 udp.BeginReceive 定义的回调函数。然后回调函数通过调用 udp.EndReceive 获取数据,最后将其存储到字符串中。当 Nav 想要通过一个简单的属性获取数据时,它可以检索该字符串。

    public string GetMessage { get { return(message); } }

public void Start()
{
udp = new UdpClient(PORT_NUMBER);
StartListening();
}
public void Stop()
{
udp.Close();
}
private void StartListening()
{
ar_ = udp.BeginReceive(Receive, new object());
}
private void Receive(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
byte[] bytes = udp.EndReceive(ar, ref ip);
message = Encoding.ASCII.GetString(bytes);

StartListening();
}

一切都很好,除了...

Nav 调用 Start(),它发出 StartListening(),它定义了回调函数。通过 udp.EndReceive 接收数据后,它再次调用 StartListening() - 这部分工作正常。

然而,当 Nav 调用 Stop() 函数时,麻烦就开始了,我知道这是因为没有对 EndReceive 的最终调用,因此没有打开 session 。

有人可能会说,为什么不在 udp.Close() 之前的 Stop() 函数中执行 EndReceive()?好吧,因为我找不到那个调用的正确参数。

事实上,我确实有一个 worker 类(Class)。我不会尝试在 Stop() 函数中关闭 session ,而是设置一个 bool 变量。下次发出回调函数时,根据该 bool 值,它不会执行 StartListening() 而是执行 upd.CLose() 。最后,为了确保有数据可以发出回调函数,我调用我的 Send() 函数发送一些单个字符。

虽然以下代码运行良好,但我知道这有点疯狂:
    public string GetMessage { get { return(message); } }

public void Start()
{
active = true;

udp = new UdpClient(PORT_NUMBER);
StartListening();
}
public void Stop()
{
active = false; // force callback function to close session
Send("x"); // issue callback function ... crazy
//udp.Close();
}
private void StartListening()
{
ar_ = udp.BeginReceive(Receive, new object());
}
private void Receive(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
byte[] bytes = udp.EndReceive(ar, ref ip);
message = Encoding.ASCII.GetString(bytes);

if (active) StartListening(); else udp.Close();
}

在调用 udp.Close() 之前,是否有人提示如何在我的 Stop() 函数中发出 EndReceive()?

提前致谢

迈克尔

最佳答案

我最近找到了一个解决方案,只需使用 Thread() 而不是异步接收 - 到目前为止效果很好:

public class Bos_UDP
{
private UdpClient udp;
const int PORT_NUMBER = 15000;
private String message = "";
public Thread receiveThread;

public string GetMessage { get { return(message); } }

public void Start()
{
udp = new UdpClient(PORT_NUMBER);

receiveThread = new Thread(ThreadReceive);
receiveThread.Start();
}
public void Stop()
{
receiveThread.Abort(new object());
udp.Close();
}
public void ThreadReceive()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
while (true)
{
var data = udp.Receive(ref ip);
message = Encoding.Default.GetString(data);
}
}
public void Send(string message)
{
UdpClient client = new UdpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("255.255.255.255"), PORT_NUMBER);
byte[] bytes = Encoding.ASCII.GetBytes(message);
client.Send(bytes, bytes.Length, ip);
client.Close();
}
}

关于sockets - UDP 客户端 - 如何在 BeginReceive 之后关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48844910/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com