C# 异步Socket 由于线程退出或应用程序请求,已放弃 I/O 操作。

tqwtshh 2012-06-05 09:15:13
本人刚接触C#异步Socket编程。当程序执行到int bytesRead = handler.EndReceive(ar)时,就会报错,“由于线程退出或应用程序请求,已放弃 I/O 操作。”不知道是为什么,还请高人指点,谢谢了。
程序如下:服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TongEx060401
{
class Program
{
private static IPAddress myIP = IPAddress.Parse("172.25.13.51");
private static IPEndPoint myServer;
private static Socket mySocket;
private static Socket handler;
private static ManualResetEvent myReset = new ManualResetEvent(false);
static void Main(string[] args)
{
Thread threadWatch = null; //负责 调用套接字, 执行 监听请求的线程
try
{
mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //定义套接字;
myServer = new IPEndPoint(myIP, 6000);
mySocket.Bind(myServer);
mySocket.Listen(200);
Console.WriteLine("启动服务器成功...");
threadWatch = new Thread(new ThreadStart(target));
//threadWatch = new Thread(target);
threadWatch.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

}
private static void target()
{
while (true)
{
//设为非终止
//允许继续等待;
myReset.Reset();
mySocket.BeginAccept(new AsyncCallback(AcceptCallback), mySocket);
//阻塞当前线程,直到收到请求信号
myReset.WaitOne();
}
}
private static void AcceptCallback(IAsyncResult ar)
{
//将事件设为终止
myReset.Set();
Socket listener = (Socket)ar.AsyncState; //获取用户定义的对象,他限定或包含关于异步操作的信息
handler = listener.EndAccept(ar);
//获取状态
StateObject state = new StateObject();
state.workSocket = handler;
Console.WriteLine("与客户建立连接。");
try
{
byte[] byteData = System.Text.Encoding.BigEndianUnicode.GetBytes("已经准备好,请通话!");
//开始发送数据
//handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
catch (Exception ee)
{
Console.WriteLine(ee.Message);
}
Thread thread = new Thread(new ThreadStart(begReceive));
thread.Start();
}
private static void SendCallback(IAsyncResult ar)
{
myReset.Reset();
try
{
handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
}
catch (Exception eee)
{
Console.WriteLine(eee.Message);
}
}
private static void begReceive()
{
myReset.Reset();
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
private static void ReadCallback(IAsyncResult ar)
{
myReset.Set();
StateObject state = (StateObject)ar.AsyncState;
Socket tt = state.workSocket;
//结束读取并获取读取字节数
int bytesRead = handler.EndReceive(ar); //在此处出错!
state.sb.Append(System.Text.Encoding.BigEndianUnicode.GetString(state.buffer, 0, bytesRead));
string content = state.sb.ToString();
state.sb.Remove(0, content.Length);
//重新开始读取数据
tt.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
}
class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
public StateObject()
{
}
}
}
...全文
900 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
tqwtshh 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
引用 2 楼 的回复:
我试着不要static,但是不知道为什么不加static的话,在其他的成员函数当中就不能使用,所以我才加的。


那你就应该解决真正的问题,不能为了让程序能够编译而不顾逻辑是否正确。

既然你在代码中有

C# code

handler = listener.EndAccept(ar);
那么多线程胡乱地更新handler变量,这显然就乱了套了!
[/Quote]

我是新手,项目要的还紧,能否请你说的再具体一些,谢谢了!
__天涯寻梦 2012-06-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
你发的代码太乱了,看看这个吧

C# code
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Parse("172.25.13.51"), 6000));
socket.Lis……
[/Quote]
有一行错了
Socket skt = (Socket)sk;
该是
Socket skt = (Socket)param;
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
我试着不要static,但是不知道为什么不加static的话,在其他的成员函数当中就不能使用,所以我才加的。
[/Quote]

那你就应该解决真正的问题,不能为了让程序能够编译而不顾逻辑是否正确。

既然你在代码中有
handler = listener.EndAccept(ar);
那么多线程胡乱地更新handler变量,这显然就乱了套了!
__天涯寻梦 2012-06-05
  • 打赏
  • 举报
回复
你发的代码太乱了,看看这个吧
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Parse("172.25.13.51"), 6000));
socket.Listen(20);

while (true)
{
// 等待请求
Socket sk = socket.Accept();

// 有了请求就启动子线程处理请求,主线程继续等待请求
ThreadPool.QueueUserWorkItem(param =>
{
Socket skt = (Socket)sk;

// 接收请求数据
byte[] buffer = new byte[1024];
skt.Receive(buffer);

// 发送回应数据
var byteData = Encoding.BigEndianUnicode.GetBytes("已经准备好,请通话!");
skt.Send(byteData);
}, sk);
}
tqwtshh 2012-06-05
  • 打赏
  • 举报
回复
我不明白您的意思,是我不应该用static,还是不用有两个Socket?
我的这个程序是控制台程序,我试着不要static,但是不知道为什么不加static的话,在其他的成员函数当中就不能使用,所以我才加的。
还请您指正。谢谢!
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
private static Socket handler;
[/Quote]

你还能有个static的handler?

111,126

社区成员

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

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

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