我在套接字编程方面有点挣扎(我不熟悉的东西),我找不到任何有助于谷歌或MSDN(可怕)的东西。抱歉这个。
基本上我有一个现有的服务,可以通过UDP接收和响应请求。我根本无法改变这一点。
我的webapp中还有一个客户端,可以调度和侦听对该服务的响应。我给出的现有客户端是一个单例,它创建一个套接字和一个响应槽数组,然后创建一个带有无限循环方法的后台线程,使得“sock.Receive()”调用并将接收到的数据推送到插槽阵列。关于这一切的所有事情对我来说都是错误的,并且无限的线程会破坏我的单元测试,所以我试图将这个服务替换为使得它的异步发送/接收的服务。
第1点:这是正确的方法吗?我想要一种非阻塞,可扩展,线程安全的服务。
我的第一次尝试大致是这样的,哪种方式有效,但我得到的数据总是比预期的短(即缓冲区没有请求的字节数),并且似乎在处理时抛出异常。
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);
}
我的第二次尝试是基于更多谷歌拖网和我经常看到的这种递归模式,但这个版本总是超时! 从未到达ARecieve。
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;
}
第2点:很明显我得到了一些非常错误的东西。
第3点:我不确定我是否正确行事。来自远程服务的数据如何进入正确的监听线程?我是否需要为每个请求创建一个套接字?
离开我的舒适区。需要帮助。
答案 0 :(得分:0)
不是解决方案,只是一个建议 - 提出最简单的代码,剥离所有线程/事件/等。从那里开始添加所需的,仅需要的复杂性。我的经验总是在这个过程中我会发现我做错了什么。
答案 1 :(得分: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;
}
生病了!
第二个代码是我们可以使用的代码和前进的方式。
但你是对的!文件不是最好的。
答案 2 :(得分:0)
您确定知道您收到了对您发送的邮件的回复吗?从套接字中删除异步行为,并尝试同步发送和接收(即使这可能会阻止您的线程)。一旦您知道此行为正常,请编辑您的问题并发布该代码,我将帮助您使用线程模型。一旦网络部分(即发送/接收)正在工作,线程模型就非常简单。
答案 3 :(得分:0)
一个可能的问题是,如果您的发送操作进入服务器,并且它在Windows设置异步侦听器之前响应。如果你没有听,那么你不会接受这些数据(与TCP不同) 尝试在发送操作之前调用beginread。