C#套接字接收异步
我习惯于同步套接字,但我现在遇到了一些麻烦,尤其是使用C#套接字接收异步,c#,sockets,asyncsocket,C#,Sockets,Asyncsocket,我习惯于同步套接字,但我现在遇到了一些麻烦,尤其是使用Socket.Receive(…)并不总是接收所有字节 这是我以前使用的代码 public byte[] Receive(int size) { var buffer = new byte[size]; var r = 0; do { // ReSharper disable once InconsistentlySynchronizedF
Socket.Receive(…)
并不总是接收所有字节
这是我以前使用的代码
public byte[] Receive(int size)
{
var buffer = new byte[size];
var r = 0;
do
{
// ReSharper disable once InconsistentlySynchronizedField
var c = _clientSocket.Receive(buffer, r, size - r, SocketFlags.None);
if (c == 0)
{
throw new SocketExtendedException();
}
r += c;
} while (r != buffer.Length);
return buffer;
}
现在我开始在Windows Phone中使用套接字,但是.Receive(..)
不可用,我成功地获得了Socket.ReceiveAsync(..)
工作,但我担心(到目前为止没有发生任何问题)这是我的新代码,我没有实现检查是否已接收所有字节,也不知道是否必须使用以下代码
private byte[] ReadBySize(int size = 4)
{
var readEvent = new AutoResetEvent(false);
var buffer = new byte[size];
var recieveArgs = new SocketAsyncEventArgs()
{
UserToken = readEvent
};
recieveArgs.SetBuffer(buffer, 0, size);
recieveArgs.Completed += recieveArgs_Completed;
_connecter.ReceiveAsync(recieveArgs);
readEvent.WaitOne();
if (recieveArgs.BytesTransferred == 0)
{
if (recieveArgs.SocketError != SocketError.Success)
throw new SocketException((int)recieveArgs.SocketError);
throw new CommunicationException();
}
return buffer;
}
void recieveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
var are = (AutoResetEvent)e.UserToken;
are.Set();
}
这是我第一次使用ReceiveAsync有人能指出我可能做错了什么或需要更改什么吗好的,我去拿了一个大的缓冲区,分批发送,中间有一个睡眠间隔,以复制“未收到所有字节”,这样我上面的代码就不会收到所有字节。对于同样使用ReceiveAsync(..)的人,这里是我的代码
private byte[] ReadBySize(int size = 4)
{
var readEvent = new AutoResetEvent(false);
var buffer = new byte[size]; //Receive buffer
var totalRecieved = 0;
do
{
var recieveArgs = new SocketAsyncEventArgs()
{
UserToken = readEvent
};
recieveArgs.SetBuffer(buffer, totalRecieved, size - totalRecieved);//Receive bytes from x to total - x, x is the number of bytes already recieved
recieveArgs.Completed += recieveArgs_Completed;
_connecter.ReceiveAsync(recieveArgs);
readEvent.WaitOne();//Wait for recieve
if (recieveArgs.BytesTransferred == 0)//If now bytes are recieved then there is an error
{
if (recieveArgs.SocketError != SocketError.Success)
throw new ReadException(ReadExceptionCode.UnexpectedDisconnect,"Unexpected Disconnect");
throw new ReadException(ReadExceptionCode.DisconnectGracefully);
}
totalRecieved += recieveArgs.BytesTransferred;
} while (totalRecieved != size);//Check if all bytes has been received
return buffer;
}
void recieveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
var are = (AutoResetEvent)e.UserToken;
are.Set();
}
我使用套接字应用程序的方式是发送一个由一些变量组成的缓冲区
[0] -> 0,1,2 0 is keep alive, 1 means there are data, 2 means a type off error occured
[1,2,3,4] size of the actual buffer I am sending
[x(size of 1,2,3,4)] the actual 'Serialized' data buffer
我建议在windows Phone中使用
BeginReceive()
,BeginReceive和Receive不可用,我也使用过BeginReceive,但它不可用,我只能使用StreamSocket或Socket(带ReceiveAsync)是的,很抱歉,我不好,没有读到它是windows Phone。你在使用TCP吗?如果是这样,您是否考虑过使用TcpClient
/TcpListener
<代码>网络流更容易使用。不幸的是,TcpClient在Windows Phone中也不可用。如果您通过在同一线程中调用ReceiveAsync
然后WaitOne
有效地使异步API同步,那么为什么还要使用异步API?您可以直接调用同步,阻塞Receive()
。因为这是2年前的事了,而且是windows phone,windows phone没有Receive(),如果您已经阅读了问题,您会看到这一点。当时我需要它。今天代码看起来大不相同谢谢,我确实错过了那部分。我从来没有想到同步api会不可用。:)我的代码现在包含TaskCompletionSource()
,摆脱了难看的AutoResetEvent
,我现在使用async/wait
,byte[]
变成了Task
,return buffer
变成了return tcs.Task代码>,接收参数已完成
也更改为容纳TaskCompletionSource@DonaldJansen你能把你的答案更新到你最近的评论吗?如果能看到async/await
实现,那就太好了!