C#异步套接字超时 [英] C# Async Socket timeouts

查看:63
本文介绍了C#异步套接字超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当标准的服务器应用程序,我正在使用

异步套接字调用来建立连接,发送和接收数据,

以及所有爵士乐。没有阻止方法是我写这个

的目标,到目前为止它已经很顺利了。但是来自阻挡世界,我想要在我的接收程序上有一些超时,我在MSDN上阅读了

a很多,在这里,我得到的印象是,一旦我设置一个

这些开始...方法一个正在运行且没有任何连接或发生的事情

我无法做任何关于取消它的事情。这是真的吗?


例如,我建立一个连接,我发送一个数据包然后我

去运行.BeginRead(。 ..)。让我们说我知道我的客户将在不到4秒的时间内回复
。如果没有回复,那么我可以确定我需要重新发送我的数据包 - 也许它没有到达那里,

也许有冲突技术在另一端,谁知道b $ b知道。我所知道的是我需要重试。但是我没有看到任何方式

来检测使用异步的超时。


我现在拥有的最佳方法是:我使用的是一个类包含

套接字和其他一些我需要知道的支持数据,这些数据都是在建立连接后构建的。这个对象就是我传入

.Begin ...异步调用并在完成时返回给我。如果

我在该类中设置了一个计时器,我可以手动关闭套接字,而

异步调用仍处于未决状态。我认为这会在我的调用函数中为.Begin ...调用抛出一个SocketException或

,所有这些都是

。除非它真的不好,因为我没有连接

了,它已经关闭了。我不能重试。我离开了我的异步电话,但是我没有打开套接字来重试。由于客户发起的通信是
,我无法直接控制何时再次重试这个

连接。


真的没有更好的方法吗?


我没有包含代码,这是一个更基于理论的问题。如果

任何人都有想法并且需要查看一些代码,我可以提供没有

的问题。


任何人都有想法?或者我应该从头开始并开始使用具有超时功能的

阻止方法。


Jason

I have a fairly standard server application that I am using
asynchronous socket calls to make connections, send and receive data,
and all of that jazz. No blocking methods was my goal in writing this
and it''s gone very well so far. But coming from the blocking world, I
want to have some timeouts on my receive routines and I after reading
a lot on MSDN and here, I get the impression that once I set one of
these Begin... methods a running and nothing connects or happens that
there is nothing I can do about canceling it. Is this really true?

For example, I make a connection, I send a packet of data, and then I
go and run .BeginRead(...). Lets say I know that my client will
respond in less than 4 seconds. If there is no response, then I can
be sure that I need to resend my packet - maybe it didn''t get there,
maybe there were collisions on the technology on the other end, who
knows. All I know is that I need to retry. But I don''t see any way
to detect a timeout using async.

The best method I have for this now: I use a class that contains the
socket and some other supporting data that I need to know that is all
built after the connection is made. This object is what I pass into
the .Begin... async calls and is returned to me when it completes. If
I set a timer in that class, I can manually close the socket while the
async call is still pending. I think this throws a SocketException or
something in my calling function for the .Begin... call and all is
well. Except it really isn''t well because I don''t have my connection
anymore, it''s closed. I can''t retry. I got out of my async call but I
don''t have an open socket to retry with. Since the communications are
initiated by the clients, I have no direct control over when this
connection will be retried again.

Is there really no better way?

I have not included code, this is a more theory based question. If
anyone has an idea and needs to see some code, I can provide that no
problem.

Anyone have any ideas? Or should I start from scratch and start using
blocking methods which HAVE a timeout feature.

Jason

推荐答案

我确实找到了这个:

http://groups.google.com/group/micro ... ... 8c632b18ab4672


根据那篇文章,我进行了.BeginReceive调用,然后我坐下来

在离开之前等待一些旗帜方法。我可以在

中使用一个计时器,我正在传递这个类,我可以从调用.BeginReceive的

线程中查看,因为我只是坐在那里

等待。如果从未设置接收到的数据标志(通过返回

委托)并且我的计时器设置了自己的complete.timed out标志我知道

我超时了。


但那又怎样?有没有办法结束原来的BeginReceive

电话?我不知道该怎么做。我可以从那里发起一个新的

BeginReceive调用,这应该不会很难,但我需要结束那个旧的

一个。

这个异步的东西对我来说是新的。它很顺利,但有时候总是有点困难

包围我的脑袋。


想法?评论?


Jason
I did just find this:

http://groups.google.com/group/micro...8c632b18ab4672

According to that post, I make my .BeginReceive call, then I sit and
wait for some flags before leaving the method. I could use a timer in
that class that I am passing around and I can check that from the
thread that called .BeginReceive, since I am just sitting there
waiting. If the received data flag is never set (by the return
delegate) AND my timer sets its own complete.timed out flag I do know
that I timed out.

But then what? Is there a way to end that original BeginReceive
call? I don''t know how to do that. I can, from there, initiate a new
BeginReceive call, that should not be hard, but I need to end that old
one.

This async stuff is new to me. It''s going well but it''s all a bit hard
to wrap my head around sometimes.

Ideas? Comments?

Jason


2008年5月28日星期三11:06:28 -0700,< Co *** *********@gmail.com写道:
On Wed, 28 May 2008 11:06:28 -0700, <Co************@gmail.comwrote:

[...]

但那又怎么样?有没有办法结束原来的BeginReceive

电话?我不知道该怎么做。我可以从那里发起一个新的

BeginReceive调用,这应该不会很难,但我需要结束旧的

一个。
[...]
But then what? Is there a way to end that original BeginReceive
call? I don''t know how to do that. I can, from there, initiate a new
BeginReceive call, that should not be hard, but I need to end that old
one.



基本上:关闭套接字。


详细版本:


发生超时时,您需要做出决定。你是否一直在等待数据上的
,还是放弃了这项操作?这种决定可以预先确定(如在用户配置的超时值中)或基于用户输入的b $ b bb(如提示用户看他们是否想要等待更久)。如果

你选择放弃操作,你就是_done_与那个套接字。

没有可靠的方法来简单地中断接收操作但是

然后在同一个插座上开始另一个。


Pete

Basically: you close the socket.

The elaborated version:

When a timeout occurs, you need to make a decision. Do you keep waiting
on the data, or do you abandon the operation? This sort of decision can
be predetermined (as in a user-configured timeout value) or based on user
input (as in prompting the user to see if they want to wait longer). If
you choose to abandon the operation, you are _done_ with that socket.
There is no reliable way to simply interrupt that receive operation but
then start another one on the same socket.

Pete


Co ************ @ gmail.com 写道:

我有一个相当标准的服务器应用程序,我正在使用

异步套接字调用来建立连接,发送和接收数据,

和所有爵士乐。没有阻止方法是我写这个

的目标,到目前为止它已经很顺利了。但是来自阻挡世界,我想要在我的接收程序上有一些超时,我在MSDN上阅读了

a很多,在这里,我得到的印象是,一旦我设置一个

这些开始...方法一个正在运行且没有任何连接或发生的事情

我无法做任何关于取消它的事情。这是真的吗?
I have a fairly standard server application that I am using
asynchronous socket calls to make connections, send and receive data,
and all of that jazz. No blocking methods was my goal in writing this
and it''s gone very well so far. But coming from the blocking world, I
want to have some timeouts on my receive routines and I after reading
a lot on MSDN and here, I get the impression that once I set one of
these Begin... methods a running and nothing connects or happens that
there is nothing I can do about canceling it. Is this really true?



是的。取消它们的唯一方法是关闭套接字,从而破坏

连接。


嗯,从技术上讲,你也可以调用CancelIoEx(),但是你需要

P / Invoke,它只能从Vista开始支持,我很确定

..NET类没有准备好因为他们的I / O在他们的支付后退了,所以我不建议这样做。

Yes. The only way to cancel them is to close the socket and thereby destroy
the connection.

Well, technically, you can also call CancelIoEx(), but you''d need to
P/Invoke, it''s only supported from Vista onwards and I''m pretty sure the
..NET classes are not prepared for having their I/O aborted behind their
backs, so I wouldn''t recommend that.


例如,我做了一个连接,我发送一个数据包,然后我去b $ b去运行.BeginRead(...)。让我们说我知道我的客户将在不到4秒的时间内回复
。如果没有回复,那么我可以确定我需要重新发送我的数据包 - 也许它没有到达那里,

也许有冲突技术在另一端,谁知道b $ b知道。我所知道的是我需要重试。但我没有看到任何方式

使用异步检测超时。
For example, I make a connection, I send a packet of data, and then I
go and run .BeginRead(...). Lets say I know that my client will
respond in less than 4 seconds. If there is no response, then I can
be sure that I need to resend my packet - maybe it didn''t get there,
maybe there were collisions on the technology on the other end, who
knows. All I know is that I need to retry. But I don''t see any way
to detect a timeout using async.



设置一个单独的计时器(你*可以*停止那些)并且不发出.BeginRead()

调用以响应发送。相反,总是在空中有一个.BeginRead()

并准备好在对方发送内容时进行处理。在其他

字样中,你的.BeginRead()应该是无状态的,你的.EndRead()应该

检查它应该对接收到的数据做什么,具体取决于你当前的/>
状态并发出新的.BeginRead(),如果它应该继续接收。不要

关闭连接,直到你真的完成它为止。


如果你遵循这种模式,你不需要在任何时候中止任何事情超时

发生,因为你总是*等着对方发送一些东西。

当他们发送的东西时,这只是你的反应'会有所不同。

Set a separate timer (you *can* stop those) and do not issue .BeginRead()
calls in response to sending. Instead, always have a .BeginRead() in the air
and be ready to process whenever the other side sends something. In other
words, your .BeginRead() should be stateless and your .EndRead() should
check what it should be doing with received data depending on your current
state and issue a new .BeginRead() if it should continue receiving. Do not
close the connection until you''re really done with it.

If you follow this pattern, you do not need to abort anything when a timeout
occurs, since you''re *always* waiting for the other side to send something.
It''s just your reactiong when they do send something that''ll be different.


任何人都有任何想法?或者我应该从头开始并开始使用具有超时功能的

阻止方法。
Anyone have any ideas? Or should I start from scratch and start using
blocking methods which HAVE a timeout feature.



这实际上是一个选项,只要如果你这样做的话,你不介意这是不可能的。如果你的服务器永远不会超过几个连接,那么经典的单独的阻塞线程就是这样。模特会工作。

它不是很有前瞻性。


-

J.
http://symbolsprose.blogspot.com


这篇关于C#异步套接字超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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