我正在尝试使用带有套接字的ReceiveAsync事件来读取数据。我可以成功地将数据发送到服务器,但是当服务器响应时,它不会显示在SocketAsyncEventArgs的缓冲区中。我使用Wireshark监控流量,我知道响应正在进行但我的应用程序没有注册它。
接收方法我做错了什么?
以下代码是我认为错误的地方。
buffer = new byte[4096];
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this._remoteEP;
args.UserToken = this._clientSocket;
args.SetBuffer(buffer, 0, buffer.Length);
this._clientSocket.ReceiveAsync(args);
byte[] udpMsg = new byte[buffer.Length];
Array.Copy(buffer, udpMsg, buffer.Length);
这是整个接收功能。
protected void ProcessReceivedMessages()
{
byte[] buffer = null;
int maxSize = AbstractNetworkUtils.GetMaxMessageSize();
while (!this._isDone)
{
Thread.Sleep(1000);
try
{
buffer = new byte[4096];
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this._remoteEP;
args.UserToken = this._clientSocket;
args.SetBuffer(buffer, 0, buffer.Length);
this._clientSocket.ReceiveAsync(args);
byte[] udpMsg = new byte[buffer.Length];
Array.Copy(buffer, udpMsg, buffer.Length);
//buffer is a byte array of size 4096 but it is always empty
byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);
if ( (mType == CoAPMessageType.CON ||
mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
{
//This is a request
CoAPRequest coapReq = new CoAPRequest();
coapReq.FromByteStream(udpMsg);
coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;
//setup the default values of host and port
//setup the default values of host and port
if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));
this.HandleRequestReceived(coapReq);
}
else
{
//This is a response
CoAPResponse coapResp = new CoAPResponse();
coapResp.FromByteStream(udpMsg);
coapResp.RemoteSender = this._remoteEP;//Setup who sent this message
//Remove the waiting confirmable message from the timeout queue
if (coapResp.MessageType.Value == CoAPMessageType.ACK ||
coapResp.MessageType.Value == CoAPMessageType.RST)
{
this._msgPendingAckQ.RemoveFromWaitQ(coapResp.ID.Value);
}
this.HandleResponseReceived(coapResp);
}
}
catch (SocketException se)
{
//Close this client connection
this._isDone = true;
this.HandleError(se, null);
}
catch (ArgumentNullException argEx)
{
this.HandleError(argEx, null);
}
catch (ArgumentException argEx)
{
this.HandleError(argEx, null);
}
catch (CoAPFormatException fEx)
{
//Invalid message..
this.HandleError(fEx, null);
}
}
}
答案 0 :(得分:0)
好的,我明白了。我为args.Completed添加了一个事件处理程序。
...
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this._remoteEP;
args.SetBuffer(buffer, 0, buffer.Length);
args.Completed += new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
byte[] udpMsg = new byte[e.BytesTransferred];
// Retrieve the data from the buffer
Array.Copy(e.Buffer, udpMsg, e.BytesTransferred);
...
}
});
this._clientSocket.ReceiveAsync(args);
...
这是整个接收功能
protected void ProcessReceivedMessages()
{
byte[] buffer = null;
int maxSize = AbstractNetworkUtils.GetMaxMessageSize();
while (!this._isDone)
{
Thread.Sleep(1000);
try
{
buffer = new byte[maxSize * 2];
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = this._remoteEP;
args.SetBuffer(buffer, 0, buffer.Length);
args.Completed += new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
byte[] udpMsg = new byte[e.BytesTransferred];
// Retrieve the data from the buffer
Array.Copy(e.Buffer, udpMsg, e.BytesTransferred);
byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);
if ((mType == CoAPMessageType.CON ||
mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
{
//This is a request
CoAPRequest coapReq = new CoAPRequest();
coapReq.FromByteStream(udpMsg);
coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;
//setup the default values of host and port
//setup the default values of host and port
if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));
this.HandleRequestReceived(coapReq);
}
else
{
//This is a response
CoAPResponse coapResp = new CoAPResponse();
coapResp.FromByteStream(udpMsg);
coapResp.RemoteSender = this._remoteEP;//Setup who sent this message
//Remove the waiting confirmable message from the timeout queue
if (coapResp.MessageType.Value == CoAPMessageType.ACK ||
coapResp.MessageType.Value == CoAPMessageType.RST)
{
this._msgPendingAckQ.RemoveFromWaitQ(coapResp.ID.Value);
}
this.HandleResponseReceived(coapResp);
}
}
});
this._clientSocket.ReceiveAsync(args);
}
catch (SocketException se)
{
//Close this client connection
this._isDone = true;
this.HandleError(se, null);
}
catch (ArgumentNullException argEx)
{
this.HandleError(argEx, null);
}
catch (ArgumentException argEx)
{
this.HandleError(argEx, null);
}
catch (CoAPFormatException fEx)
{
//Invalid message..
this.HandleError(fEx, null);
}
}
}