BeginReceive在运行时返回零长度缓冲区,并在使用逐步调试模式时正常工作 [英] BeginReceive return zero length buffer when run ,and work correctly when use step by step debug mode

查看:73
本文介绍了BeginReceive在运行时返回零长度缓冲区,并在使用逐步调试模式时正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在2个客户端之间使用asyc套接字p2p连接。

当我逐步调试双方时,我工作正常。

时我运行它,在某些点(代码中的相同位置)

当我想要接收5个字节的缓冲区时,我调用BeginReceive然后

等待AsyncWaitHandle.WaitOne( )

但它是imidiatly信号,下一次调用EndReceive返回零

字节长度,缓冲区也是空的。

这里是代码:

public static byte [] Receive(Socket OpenSocket,int length)


{


byte [] buffer = new byte [length];


int totalreceive = 0;


int _lastReceive = 0;


if(OpenSocket.Blocking)


totalreceive = OpenSocket.Receive(buffer);


else


{


IAsyncResult ar;


do


{


//在这一点上是OpenSocket.Ava ilable == 0!


ar = OpenSocket.BeginReceive(缓冲区,0,长度,SocketFlags.None,null,

null);


ar.AsyncWaitHandle.WaitOne(); //某事在收到数据之前发出信号吗?


_lastReceive = OpenSocket.EndReceive(ar);


if(_lastReceive == 0 )//当运行代码时发生,如果

一步一步地慢慢发生,那就不会发生!


{


buffer = null;


抛出新的异常(无数据接收);


}


totalreceive + = _lastReceive;


} while(totalreceive< length);


}

返回缓冲区;


}


我的问题是什么?我不想使用同步调用,因为

会话的其余部分也是异步的,所以我只想要async - sinc就像forthis

部分代码另外,当处于调试模式时,我将

OpenSocket.Blocking更改为True - 使其调用同步接收而不是

beginrecv,也返回零长度缓冲区


任何想法?

Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i''ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don''t want to use sync calls because the rest of the
session is async also , so I only want to makethe async - sinc like forthis
part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?

推荐答案

你所说的是问题,但是你可以解决这个问题。


如果你把一个对象发送到另一个客户端,它并不总是到达那里。

但如果你调试,它会吗?问题是你'丢失''字节?

" semedao" < se ***** @ community.nospamwrote in message

news:ei ************** @ TK2MSFTNGP02.phx.gbl ...
Bit confused by what you are saying is the problem but can you calrify.

If you send an object to the other client, it is not always getting there.
But if you debug, it does? Is the problem that you are ''losing'' bytes?
"semedao" <se*****@community.nospamwrote in message
news:ei**************@TK2MSFTNGP02.phx.gbl...

我在2个客户端之间使用asyc套接字p2p连接。

当我逐步调试双方时,我不工作好的。

当我运行它时,在某些点(代码中的相同位置)

当我想要接收5个字节的缓冲区时,我调用BeginReceive然后

等待AsyncWaitHandle.WaitOne()

但它是imidiatly信号,下一次调用EndReceive返回零

字节长度,缓冲区也是空的。

这里是代码:

public static byte [] Receive(Socket OpenSocket,int length)


{


byte [] buffer = new byte [length];


int totalreceive = 0;


int _lastReceive = 0;


if(OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);


其他

{


IAsyncResult ar;


do


{


//此时OpenSocket.Available == 0!


ar = OpenSocket.BeginReceive(缓冲区,0,长度,SocketFlags。无,null,

null);


ar.AsyncWaitHandle.WaitOne(); //某事在数据之前发出信号

收到了吗?


_lastReceive = OpenSocket.EndReceive(ar);


if(_lastReceive == 0)//在运行代码时发生,如果

一步一步慢慢发生doeas!


{


buffer = null;


抛出新的异常(无数据接收);


}


totalreceive + = _lastReceive;


} while(totalreceive< length);


}


返回缓冲区;


}


我的问题是什么?我不想使用同步调用,因为会话的其余部分也是异步的,所以我只想要async - sinc就像

这部分代码另外,当处于调试模式时,我将

OpenSocket.Blocking更改为True - 使其调用同步接收而不是

beginrecv,也返回零长度缓冲区


任何想法?

Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i''ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data
received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don''t want to use sync calls because the rest of
the session is async also , so I only want to makethe async - sinc like
forthis part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?



不,

我在2个客户端之间发送了一些recv对话

模式是异步套接字。

当我来到代码中的某个位置时我想要恢复5个字节,

recv在收到的字节之前返回,EndRecv()的长度为0

(零),

我使用异步结果BeginReceive()WaitHandle.WaitOne()在这个线程上阻止

,直到字节到来,但是,它没有阻塞并返回为

我如上所述。 />
当我调试这两者的这个过程时客户一步一步,正常工作

并返回5个字节!

所以,我找不到它发生了! />
丹尼尔 < da ***** @ vestryonline.comwrote in message

news:ub ************** @ TK2MSFTNGP05.phx.gbl ...
No,
I have some send recv conversation between 2 clients
the mode is async sockets.
when I come to some location in the code that I want to recv 5 bytes , the
recv return before the bytes received , the length of the EndRecv() is 0
(zero) ,
I use the async result of the BeginReceive() WaitHandle.WaitOne() to block
on this thread until the bytes come , but , it does not block and return as
I described above.
When I debug this process of the both clients STEP by STEP , it''s work
correctly and return those 5 bytes !
so , I can''t find whay it''s happen !
"Daniel" <Da*****@vestryonline.comwrote in message
news:ub**************@TK2MSFTNGP05.phx.gbl...

对你所说的问题感到困惑,但是你可以进行校准。


如果你把一个对象发送到另一个客户端,它并不总是到那里。

但如果你调试,它呢?问题是你'丢失''字节?


" semedao" < se ***** @ community.nospamwrote in message

news:ei ************** @ TK2MSFTNGP02.phx.gbl ...
Bit confused by what you are saying is the problem but can you calrify.

If you send an object to the other client, it is not always getting there.
But if you debug, it does? Is the problem that you are ''losing'' bytes?
"semedao" <se*****@community.nospamwrote in message
news:ei**************@TK2MSFTNGP02.phx.gbl...

>我在两个客户端之间使用asyc套接字p2p连接。
当我一步一步地调试双方时,我的工作正常。
当我运行它时,在某些点(代码中的相同位置)
当我想要接收5字节缓冲区时,我调用BeginReceive然后
等待AsyncWaitHandle.WaitOne()这里是代码:
public static byte [] Receive(Socket) OpenSocket,int length)

} byte [] buffer = new byte [length];

int totalreceive = 0;

int _lastReceive = 0;

if(OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{IAsyncResult ar;



//
// OpenSocket.Available == 0!
ar = OpenSocket.BeginReceive(缓冲区,0,长度,SocketFlags.None,null,
null);

ar.AsyncWaitHandle.WaitOne(); //某事在收到数据之前发出信号

_lastReceive = OpenSocket.EndReceive(ar);

if(_lastReceive == 0)//发生当运行代码时,如果
一步一步慢慢地发生doeas!



缓冲区= null;

抛出新的异常(无数据接收);

}

totalreceive + = _lastReceive;

} while(totalreceive< length);

}

返回缓冲区;

}

我的问题是什么?我不想使用同步调用,因为会话的其余部分也是异步的,所以我只想在执行调试模式的同时使用async - sinc就像这部分代码一样我将
OpenSocket.Blocking更改为True - 因为它调用同步接收而不是
beginrecv,还返回零长度缓冲区

任何想法?

>Hi , I am using asyc sockets p2p connection between 2 clients.
when I debug step by step the both sides , i''ts work ok.
when I run it , in somepoint (same location in the code)
when I want to receive 5 bytes buffer , I call the BeginReceive and then
wait on AsyncWaitHandle.WaitOne()
but it is signald imidiatly , and the next call to EndReceive return zero
bytes length , also the buffer is empty.
here is the code:
public static byte[] Receive(Socket OpenSocket, int length)

{

byte[] buffer = new byte[length];

int totalreceive = 0;

int _lastReceive = 0;

if (OpenSocket.Blocking)

totalreceive = OpenSocket.Receive(buffer);

else

{

IAsyncResult ar;

do

{

//in this point the OpenSocket.Available == 0 !

ar = OpenSocket.BeginReceive(buffer, 0, length, SocketFlags.None, null,
null);

ar.AsyncWaitHandle.WaitOne(); // something "signald it before data
received?

_lastReceive = OpenSocket.EndReceive(ar);

if (_lastReceive == 0) // happen when run the code , doeas not happen if
step by step slowly!

{

buffer = null;

throw new Exception("No data receive");

}

totalreceive += _lastReceive;

} while (totalreceive < length);

}

return buffer;

}

what is my problem ? I don''t want to use sync calls because the rest of
the session is async also , so I only want to makethe async - sinc like
forthis part ofthe code , also , when in the debug mode I change the
OpenSocket.Blocking to True - cause it to call sync receive instead of
beginrecv , also return with zero length buffer

any ideas ?




" semedao" < se ***** @ community.nospamwrote in message

news:en ************** @ TK2MSFTNGP06.phx.gbl ...
"semedao" <se*****@community.nospamwrote in message
news:en**************@TK2MSFTNGP06.phx.gbl...

[...]

我使用BeginReceive()的异步结果WaitHandle.WaitOne()阻止
$ b这个线程上的$ b直到字节到来,但是,它没有阻塞并返回

,如上所述。

当我调试这两个客户端的进程时STEP STEP,它正常工作

正确并返回这5个字节!

所以,我找不到它发生了!
[...]
I use the async result of the BeginReceive() WaitHandle.WaitOne() to block
on this thread until the bytes come , but , it does not block and return
as I described above.
When I debug this process of the both clients STEP by STEP , it''s work
correctly and return those 5 bytes !
so , I can''t find whay it''s happen !



免责声明:虽然我已经完成了很多Winsock编程,但我还没有在.NET中使用

套接字。不过,我认为这是一个很好的猜测

发生了什么...


我相信你误解了什么行为Begin / EndReceive是

(可能是因为文档有误导性或不正确)。特别是在

中,假设它的工作方式与.NET中的其他异步内容一样,那么当你<实际上并不等待数据出现在非阻塞套接字上br />
等待AsyncResult或调用EndReceive)。所有这一切都是因为

特定的Receive调用发生在另一个线程上,所以你自己的

线程可以继续工作。但在另一个线程中,它就像是直接接收

。没有额外的处理来检查数据是否可用




所以,在这种情况下你有一个非阻塞套接字,因为没有数据,接收操作

基本上立即完成,当你检查

结果时,没有数据。


通过单步执行(或者可能是任何其他延迟),您可以留出时间让

数据进入套接字的接收缓冲区并可以接收
$ b线程中的$ b。


换句话说,如果

你有一个阻塞套接字,那么使用BeginReceive而不是Receive是有意义的。如果你有一个非阻塞套接字,你需要

继续使用你选择的普通i / o通知机制来使用该套接字。


恕我直言,EndReceive返回一个值有点奇怪。如果它是完全类似于正常的Winsock行为,它会抛出(或返回,在重载中返回
作为参数返回异常)的异常

没有数据存在(无论等同于WSAEWOULDBLOCK是什么......也就是说,

a SocketException,其中ErrorCode设置为WSAEWOULDBLOCK)。


我意识到以上所有内容都与

文档直接矛盾(特别是,EndReceive的文档部分读取了

" EndReceive方法将阻止,直到数据可用)。但是考虑到你看到的

行为,并且鉴于Winsock(底层的Win32 API)实际上是如何工作的,我认为它更有可能是文档是错误的。

在非阻塞套接字上进行EndReceive阻塞将是非常重要的

(虽然不是非常困难)并且这样做会大大减少

结束......行为的一致性。功能。


所有这一切,快速查看.NET套接字文档并没有发现任何我认为正常使用的内容一个非阻塞插座
除了Select之外的
。也就是说,你可以获得并设置阻止属性,但是

除了调用Sockets之外我什么也看不见。选择查找

它'''在套接字上调用Receive或Send是合理的。所以为了解决上面的

,我能看到的唯一解决方案是使用Select方法等待套接字变得可读(当然,取决于。) NET

执行Select,你可能需要循环,直到你得到你想要的数据(或任何数据)...在Winsock中,调用select ()确实

不保证当你接到对recv()的调用时,你实际上会得到

任何数据,尽管大多数情况都是如此)。


如果你正在使用Blocking属性,我认为你实际上知道了关于Select和任何其他相似机制的
,所以希望有'

这里有足够的信息让你工作起来。


Pete

Disclaimer: while I''ve done plenty of Winsock programming, I haven''t used
sockets in .NET yet. Still, I have what I think is a good guess as to
what''s going on...

I believe that you misunderstand what the behavior of Begin/EndReceive is
(possibly because the documentation is misleading or incorrect). In
particular, assuming it works like the other async stuff in .NET, it does
NOT actually wait for data to be present on a non-blocking socket when you
wait on the AsyncResult or call EndReceive). All it does is cause the
particular call to Receive to happen on a different thread so that your own
thread can continue working. But in the other thread, it''s like calling
Receive directly. There''s no additional processing to check for data being
available.

So, in this case you''ve got a non-blocking socket, and the receive operation
completes essentially immediately since there''s no data, and when you check
the results there is no data.

By stepping through (or probably any other delay), you allow time for the
data to get into the socket''s receive buffer and become available to receive
in your thread.

In other words, using BeginReceive instead of Receive only makes sense if
you have a blocking socket. If you have a non-blocking socket, you need to
continue to use the normal i/o notification mechanism that you''ve chosen for
use with that socket.

IMHO, it''s a little odd that EndReceive returns a value. If it were
completely analogous to the normal Winsock behavior, it''d throw (or return,
in the overload that returns an exception as a parameter) an exception when
no data is present (whatever the equivalent to WSAEWOULDBLOCK is...that is,
a SocketException where ErrorCode is set to WSAEWOULDBLOCK).

I realize that all of the above is in direct contradiction to the
documentation (in particular, the documentation for EndReceive reads in part
"The EndReceive method will block until data is available"). But given the
behavior you''re seeing, and given how Winsock (the underlying Win32 API)
actually works, I think it''s more likely that the documentation is wrong.
Making EndReceive blocking on a non-blocking socket would be non-trivial
(though not terribly difficult) and doing so would significantly reduce the
uniformity of the behavior of "End..." functions.

All that said, a quick look through the .NET Sockets documentation didn''t
turn up anything that I recognized as a normal use of a non-blocking socket
other than Select. That is, you can get and set the Blocking property, but
I don''t see any means other than calling Sockets.Select to find out when
it''s reasonable to call Receive or Send on a socket. So to address the
above, the only solution I can see is to use the Select method to wait until
the socket becomes readable (and of course, depending on the .NET
implementation of Select, you may have to loop until you get the data you
want (or any data at all for that matter...in Winsock, calling select() does
not guarantee that when you get to the call to recv() you will actually get
any data back, even though most often that is the case).

If you are using the Blocking property, I assume that you actually know
about Select and any other mechanism that is similar, so hopefully there''s
enough information here for you to get things working.

Pete


这篇关于BeginReceive在运行时返回零长度缓冲区,并在使用逐步调试模式时正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆