C# 异步UDP套接字的问题

C# 异步UDP套接字的问题,c#,sockets,.net-2.0,udp,C#,Sockets,.net 2.0,Udp,我正在为socket编程而挣扎,这是我一点都不熟悉的东西,我也找不到谷歌或MSDN的任何帮助。抱歉这么长时间 基本上,我有一个通过UDP接收和响应请求的现有服务。我根本改变不了这个 我的webapp中还有一个客户端,用于发送和侦听对该服务的响应。我得到的现有客户端是一个singleton,它创建一个套接字和一个响应插槽数组,然后使用一个无限循环方法创建一个后台线程,使sock.Receive调用并将接收到的数据推送到插槽数组中。关于这一点的所有事情在我看来都是错误的,无限线程破坏了我的单元测试,

我正在为socket编程而挣扎,这是我一点都不熟悉的东西,我也找不到谷歌或MSDN的任何帮助。抱歉这么长时间

基本上,我有一个通过UDP接收和响应请求的现有服务。我根本改变不了这个

我的webapp中还有一个客户端,用于发送和侦听对该服务的响应。我得到的现有客户端是一个singleton,它创建一个套接字和一个响应插槽数组,然后使用一个无限循环方法创建一个后台线程,使sock.Receive调用并将接收到的数据推送到插槽数组中。关于这一点的所有事情在我看来都是错误的,无限线程破坏了我的单元测试,所以我尝试用一个异步发送/接收的服务来代替这个服务

第一点:这是正确的方法吗?我想要一个非阻塞、可扩展、线程安全的服务

我的第一次尝试大致上是这样的,这是一种工作方式,但我得到的数据总是比预期的短,即缓冲区没有请求的字节数,并且在处理时似乎抛出异常

private Socket MyPreConfiguredSocket;

public object Query()
{
    //build a request

    this.MyPreConfiguredSocket.SendTo(MYREQUEST, packet.Length, SocketFlags.Multicast, this._target);

    IAsyncResult h = this._sock.BeginReceiveFrom(response, 0, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), this._sock);

    if (!h.AsyncWaitHandle.WaitOne(TIMEOUT)) { throw new Exception("Timed out"); }

    //process response data (always shortened)
}

private void ARecieve (IAsyncResult result) 
{
    int bytesreceived = (result as Socket).EndReceiveFrom(result, ref this._target);
}
我的第二次尝试是基于更多的谷歌拖网和我经常看到的递归模式,但这个版本总是超时!它永远不会到达阿雷西耶夫

public object Query()
{
    //build a request

    this.MyPreConfiguredSocket.SendTo(MYREQUEST, packet.Length, SocketFlags.Multicast, this._target);

    State s = new State(this.MyPreConfiguredSocket);

    this.MyPreConfiguredSocket.BeginReceiveFrom(s.Buffer, 0, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), s);

    if (!s.Flag.WaitOne(10000)) { throw new Exception("Timed out"); } //always thrown

    //process response data
}

private void ARecieve (IAsyncResult result) 
{
    //never gets here!
    State s = (result as State);
    int bytesreceived = s.Sock.EndReceiveFrom(result, ref this._target);

    if (bytesreceived > 0)
    {
        s.Received += bytesreceived;

        this._sock.BeginReceiveFrom(s.Buffer, s.Received, BUFFER_SIZE, SocketFlags.None, ref this._target, new AsyncCallback(ARecieve), s);
    }
    else
    {
        s.Flag.Set();
    }
}

private class State
{
    public State(Socket sock)
    {
        this._sock = sock;
        this._buffer = new byte[BUFFER_SIZE];
        this._buffer.Initialize();
    }

    public Socket Sock;    
    public byte[] Buffer;    
    public ManualResetEvent Flag = new ManualResetEvent(false);  
    public int Received = 0;
}
第二点:很明显,我犯了很大的错误

第三点:我不确定我是否正确处理了这个问题。来自远程服务的数据是如何到达正确的侦听线程的?我是否需要为每个请求创建套接字


离开我的舒适区。需要帮助。

不是你的解决方案,只是一个建议-想出最简单的代码,去除所有线程/事件/等。从那里开始增加所需的,而且只需要的复杂性。我的经验是,在这个过程中,我会发现我做错了什么。

那么你的SUDO计划大纲如下

Socket MySocket;
Socket ResponceSocket;

byte[] Request;
byte[] Responce;

public byte[] GetUDPResponce()
{
    this.MySocket.Send(Request).To(ResponceSocket);

    this.MySocket.Receive(Responce).From(ResponceSocket);

    return Responce;
}
我会尽力帮忙的! 第二个代码帖子是我们可以使用的,也是我们前进的方向


但你是对的!文档不是最好的。

您是否确定收到了对您发送的消息的回复?从套接字中删除异步行为,并尝试同步发送和接收,即使这可能会暂时阻塞线程。一旦您知道这个行为是有效的,编辑您的问题并发布代码,我将帮助您使用线程模型。一旦网络部分(即发送/接收)开始工作,线程模型就非常简单。

一个可能的问题是,发送操作是否转到服务器,并且它在windows设置异步侦听器之前做出响应。如果你不在听,数据将不会被你方接受,这与TCP不同
尝试在发送操作之前调用beginread。

问题是,我就是这样做到这一点的:你知道UDT库吗?用CSharp试试看