Socket异步通讯,如何设定连接等待时间?

diffmaker 2010-03-23 04:20:28
利用Socket异步连接远程,发出异步连接请求后,在连不上的情况下,等待的时间比较长,WinForm卡在那里不动了,我这样改代码正确吗?该如何写呢?代码如下:

_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(_ip), _port);
_client.Ttl = 10;//这句有效吗?
_client.BeginConnect(ipep, new AsyncCallback(ConnectCallback), _client);
_connectDone.WaitOne(100, true);//第二个参数该用false还是用true
//连接成功后,异步发送数据
......


谢谢指点!
...全文
346 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
manager2000 2011-04-25
  • 打赏
  • 举报
回复
没有写过这方面的代码
diffmaker 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 xingyuebuyu 的回复:]
C# code
Socket _client;
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, S……
[/Quote]

多谢啦
diffmaker 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sp1234 的回复:]
其实你的理由很牵强。

其实我们像迅雷那样同时启动20个异步传输操作(而更多地则等待之前有传输结束了才开始),或者假设我们在定时器的帮助下每1秒钟给下一个的“远程”传送数据,那也都是异步的观念。不论怎么写,都用不到你所写的 WaitOne。

关键是你从msdn的烂“范例”上看到这这个东西,随便抄来就用了。如果不抄袭它,自己设计呢?
[/Quote]

是的,因为没有写过这方面的代码,就看范例来写了。谢谢你的耐心指教。我改用同步试试。
  • 打赏
  • 举报
回复
其实你的理由很牵强。

其实我们像迅雷那样同时启动20个异步传输操作(而更多地则等待之前有传输结束了才开始),或者假设我们在定时器的帮助下每1秒钟给下一个的“远程”传送数据,那也都是异步的观念。不论怎么写,都用不到你所写的 WaitOne。

关键是你从msdn的烂“范例”上看到这这个东西,随便抄来就用了。如果不抄袭它,自己设计呢?
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 diffmaker 的回复:]
引用 2 楼 sp1234 的回复:
这根本不是真正的异步编程,因为你使用了信号量阻塞机制,用异步编程的语句可是干了同步操作的事情。

如果要异步编程,就不要搞什么 WaitOne,那就没有这种问题了。


因为我要给多个远程传送数据,为了不影响其他的传送,所以才这样的
[/Quote]

那你何必写什么 BeginConnect 呢,同步Connect不就行了?画蛇添足了。
guyehanxinlei 2010-03-23
  • 打赏
  • 举报
回复
不是实际意义上的异步通讯
xingyuebuyu 2010-03-23
  • 打赏
  • 举报
回复
           Socket   _client;
_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(_ip), _port);
_client.Ttl = 10;//这句有效吗?
IAsyncResult ias= _client.BeginConnect(ipep, new AsyncCallback(ConnectCallback), _client);


int i = System.Environment.TickCount;
//timeout 1000ms
int timeout=1000;
while (System.Environment.TickCount - i <= timeout)
{
if (_client.Connected == true)
{
MessageBox.Show("connected success!");
break;
}
Application.DoEvents();
}

if (_client.Connected == false)
{
ias.AsyncWaitHandle.WaitOne(0, false);
MessageBox.Show("connected timeout");
}


你那个程式在运行时在连接的过程中界面仍然会没响应的。
diffmaker 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sp1234 的回复:]
这根本不是真正的异步编程,因为你使用了信号量阻塞机制,用异步编程的语句可是干了同步操作的事情。

如果要异步编程,就不要搞什么 WaitOne,那就没有这种问题了。
[/Quote]

因为我要给多个远程传送数据,为了不影响其他的传送,所以才这样的
xingyuebuyu 2010-03-23
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/zh-cn/library/kzy257t0.aspx

只有从非默认托管上下文内部调用 WaitOne 方法,exitContext 参数才有效。如果线程位于从 ContextBoundObject 派生的类实例的调用内部,则可能会发生这种情况。即使当前正在执行不是从 ContextBoundObject 派生的类(如 String)中的一个方法,只要 ContextBoundObject 位于当前应用程序域中的堆栈上,就可以在非默认上下文中执行。

当在非默认上下文中执行代码时,为 exitContext 指定 true 会导致线程在执行 WaitOne 方法之前退出该非默认托管上下文(即转换为默认上下文)。对 WaitOne 方法的调用完成之后,该线程返回到原始的非默认上下文。

这在上下文绑定类具有 SynchronizationAttribute 时会很有用。在这种情况下,将自动对类成员的所有调用进行同步,同步范围是类的整个代码部分。如果成员调用堆栈中的代码调用 WaitOne 方法并将 exitContext 指定为 true,则线程将退出同步域,这样,在调用该对象的任何成员时被阻止的线程便可以继续运行。当 WaitOne 方法返回时,执行调用的线程必须等待重新进入同步域。


用false就好了
  • 打赏
  • 举报
回复
这根本不是真正的异步编程,因为你使用了信号量阻塞机制,用异步编程的语句可是干了同步操作的事情。

如果要异步编程,就不要搞什么 WaitOne,那就没有这种问题了。
diffmaker 2010-03-23
  • 打赏
  • 举报
回复
C#
public virtual bool WaitOne (
int millisecondsTimeout,
bool exitContext
)

参数
millisecondsTimeout
等待的毫秒数,或为 Timeout.Infinite (-1),表示无限期等待。

exitContext
为 true,则等待之前先退出上下文的同步域(如果在同步上下文中),然后在稍后重新获取它;否则为 false。 这个参数不理解,能具体说一下吗?

返回值
如果当前实例收到信号,则为 true;否则为 false。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧