socket编程时使用异步接收,socket.EndReceive(ar)怎么设置可以不引发异常呢?

andyqq8 2009-07-30 05:56:36

System.Net.Sockets.SocketException: 由于线程退出或应用程序请求,已放弃 I/O 操作。
在 System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
在 WindowsFormsApplication7.httppost.ReadCallback(IAsyncResult ar) 位置 C:\Documents and Settings\sdo\My Documents\Visual Studio 2008\Projects\WindowsFormsApplication7\WindowsFormsApplication7\Form1.cs:行号 383


==============================
一共两个问题,一问异步接收在包未知的情况下如何判断接收完了,
二问使用socket.Close();方法后,总是会引发socket.EndReceive(ar)异常,
怎么设置可以不引发异常呢?
我想使用close方法后,退出ReadCallback函数应该能解决这个问题,可是该怎么退呢?
...全文
1166 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
liupenglove 2009-07-31
  • 打赏
  • 举报
回复
socket这个到底是做什么用的?
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
顶一下。相信初学异步socket的朋友都会遇到这问题
dancingbit 2009-07-30
  • 打赏
  • 举报
回复
异步操作本来就复杂。
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 dancingbit 的回复:]
类定义中: bool closed=false;
执行Close方法后closed=true;
判断条件改为:if (bytesRead > 0 && !closed)

[/Quote]
谢谢楼上的。。。绕了一圈。。。我又回到同步了。。。还是同步简单易处理。。。异步太麻烦了
dancingbit 2009-07-30
  • 打赏
  • 举报
回复
类定义中: bool closed=false;
执行Close方法后closed=true;
判断条件改为:if (bytesRead > 0 && !closed)
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
呵呵谢谢楼上的网友热心回复呀。积分是零还天天问大家问题。不好意思呀
Soloboy1020 2009-07-30
  • 打赏
  • 举报
回复
有很多.NET框架不会帮你处理的啊 都要自己控制
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
我把上面的放到else里面后。又出现了好多timewait的半连接。这样有些浪费呀
=======================================

放到上面会引发异常,但是没有半连接出现。。。放到if下面的if的else分支里。不异发异常,但是会出现许多半连接。。。
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dancingbit 的回复:]
if (bytesRead > 0)
------------------------

仅仅以这个作为判断条件,只要有数据到达,便会开始下一次的异步接收。
可以在执行Close之后设置个标志,在这个地方也检查一下这个标志。
[/Quote]

可以在执行Close之后设置个标志,在这个地方也检查一下这个标志。
这里如何检查呀,可否给个示范。我是菜鸟勿怪呵呵
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 soloboy1020 的回复:]
引用 5 楼 andyqq8 的回复:
我现在算是半解决了。。。把下面这行clientSocket.BeginReceive(state.buffer, 0, MyObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 放到if 里面的if的else分支里。没有读取到指定内容就运行上面的,如果读取到了就调用close(),  所以算是解决了一半呵呵

现在的新问题:
还有。如果创建这个BeginReceive的线程终止了,也还是会引发EndReceive(ar)的异常。这个有啥办法能解决吗?

我在 textbox1.append(srecv+"当前时间"),如果发过来的包分两个,就会出现两个“当前时间”。这是为什么呢?


我说的是在ReadCallback里面判断...
两次是因为你接收了两次啊
[/Quote]
这个是的呵呵,能不能像同步的do while那样只输出一时间呢?

我把上面的放到else里面后。又出现了好多timewait的半连接。这样有些浪费呀
Soloboy1020 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 andyqq8 的回复:]
我现在算是半解决了。。。把下面这行clientSocket.BeginReceive(state.buffer, 0, MyObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 放到if 里面的if的else分支里。没有读取到指定内容就运行上面的,如果读取到了就调用close(),  所以算是解决了一半呵呵

现在的新问题:
还有。如果创建这个BeginReceive的线程终止了,也还是会引发EndReceive(ar)的异常。这个有啥办法能解决吗?

我在 textbox1.append(srecv+"当前时间"),如果发过来的包分两个,就会出现两个“当前时间”。这是为什么呢?

[/Quote]
我说的是在ReadCallback里面判断...
两次是因为你接收了两次啊
dancingbit 2009-07-30
  • 打赏
  • 举报
回复
if (bytesRead > 0)
------------------------

仅仅以这个作为判断条件,只要有数据到达,便会开始下一次的异步接收。
可以在执行Close之后设置个标志,在这个地方也检查一下这个标志。
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
我现在算是半解决了。。。把下面这行clientSocket.BeginReceive(state.buffer, 0, MyObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 放到if 里面的if的else分支里。没有读取到指定内容就运行上面的,如果读取到了就调用close(), 所以算是解决了一半呵呵

现在的新问题:
还有。如果创建这个BeginReceive的线程终止了,也还是会引发EndReceive(ar)的异常。这个有啥办法能解决吗?

我在 textbox1.append(srecv+"当前时间"),如果发过来的包分两个,就会出现两个“当前时间”。这是为什么呢?

Soloboy1020 2009-07-30
  • 打赏
  • 举报
回复
会调用的
判断 Socket.Connected
自己添加个 Bool 类型的变量 判断是否Shotdown了.
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
在执行 到那个异常语句之前的时候,连接已经释放了,socket对象不存在了。 所以引发异常。。。
================================================
我的问题是使用close()连接释放后怎么退出ReadCallback不再进行socket.EndReceive(ar); 呢?
andyqq8 2009-07-30
  • 打赏
  • 举报
回复
private void ReadCallback(IAsyncResult ar)
{
MyObject state = (MyObject)ar.AsyncState;
Socket clientSocket = state.workSocket;
string srecv = "";
try
{

Int32 bytesRead = clientSocket.EndReceive(ar);

if (bytesRead > 0)
{
srecv = (Encoding.Default.GetString(state.buffer, 0, bytesRead));
clientSocket.BeginReceive(state.buffer, 0, MyObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

==========================================
clientSocket.BeginReceive(state.buffer, 0, MyObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

谢谢楼上回复,主要问题是上面这行 , 我socket.Close()后,怎么不再运行 ReadCallback呢? 否则怎么操作都会引发异常的。
先使用Shutdown再使用close也是一样会引异发常,而且在这里面使用Shutdown会出现一大堆wait_的半连接。
Soloboy1020 2009-07-30
  • 打赏
  • 举报
回复
1,是用的TCP么? TPC是流的,所以要自己判断包是不是接收完了,是不是一次过来多个包
2,先 Shutdown 后 Close 看下

110,533

社区成员

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

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

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