现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作

华宇智能 2015-06-07 10:57:28
//****此处报错******<现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作>
e.SetBuffer(e.Offset, btyArray.Length);
213行报错,在群发指令到活动连接的时候,有了解的帮忙解答下,谢谢!!



using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace Server_Program
{
/// <summary>
/// 基于SocketAsyncEventArgs 实现 IOCP 服务器
/// </summary>
internal sealed class IoServer
{
#region 变量定义

/// <summary>
/// 监听Socket,用于接受客户端的连接请求
/// </summary>
private Socket listenSocket;

/// <summary>
/// 用于服务器执行的互斥同步对象
/// </summary>
private static Mutex mutex = new Mutex();

/// <summary>
/// 用于每个I/O Socket操作的缓冲区大小
/// </summary>
private Int32 bufferSize;

/// <summary>
/// 服务器上连接的客户端总数
/// </summary>
private Int32 numConnectedSockets;

/// <summary>
/// 服务器能接受的最大连接数量
/// </summary>
private Int32 numConnections;

/// <summary>
/// 完成端口上进行投递所用的IoContext对象池
/// </summary>
private IoContextPool ioContextPool;

/// <summary>
/// 主窗体
/// </summary>
public MainForm mainForm;

#endregion

#region 构造函数

/// <summary>
/// 构造函数,建立一个未初始化的服务器实例
/// </summary>
/// <param name="numConnections">服务器的最大连接数据</param>
/// <param name="bufferSize"></param>
internal IoServer(Int32 numConnections, Int32 bufferSize)
{
this.numConnectedSockets = 0;
this.numConnections = numConnections;
this.bufferSize = bufferSize;

this.ioContextPool = new IoContextPool(numConnections);

// 为IoContextPool预分配SocketAsyncEventArgs对象
for (Int32 i = 0; i < this.numConnections; i++)
{
SocketAsyncEventArgs ioContext = new SocketAsyncEventArgs();
ioContext.Completed += new EventHandler<SocketAsyncEventArgs>(OnIOCompleted);
ioContext.SetBuffer(new Byte[this.bufferSize], 0, this.bufferSize);

// 将预分配的对象加入SocketAsyncEventArgs对象池中
this.ioContextPool.Add(ioContext);
}
}

#endregion

#region socket数据收发

/// <summary>
/// 当Socket上的发送或接收请求被完成时,调用此函数
/// </summary>
/// <param name="sender">激发事件的对象</param>
/// <param name="e">与发送或接收完成操作相关联的SocketAsyncEventArg对象</param>
private void OnIOCompleted(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
this.ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
this.ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
}

/// <summary>
///接收完成时处理函数
/// </summary>
/// <param name="e">与接收完成操作相关联的SocketAsyncEventArg对象</param>
private void ProcessReceive(SocketAsyncEventArgs e)
{
// 检查远程主机是否关闭连接
if (e.BytesTransferred > 0)
{
if (e.SocketError == SocketError.Success)
{
Socket s = (Socket)e.UserToken;
//判断所有需接收的数据是否已经完成
if (s.Available == 0)
{
// 设置发送数据
byte[] bty = new byte[12] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x08 };
Array.Copy(bty, 0,e.Buffer, 0, bty.Length);
e.SetBuffer(e.Offset, bty.Length);
if (!s.SendAsync(e)) //投递发送请求,这个函数有可能同步发送出去,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
{
// 同步发送时处理发送完成事件
this.ProcessSend(e);
}
}
else if (!s.ReceiveAsync(e)) //为接收下一段数据,投递接收请求,这个函数有可能同步完成,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
{
// 同步接收时处理接收完成事件
this.ProcessReceive(e);
}
}
else
{
this.ProcessError(e);
}
}
else
{
this.CloseClientSocket(e);
}
}

/// <summary>
/// 发送完成时处理函数
/// </summary>
/// <param name="e">与发送完成操作相关联的SocketAsyncEventArg对象</param>
private void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Socket s = (Socket)e.UserToken;

//接收时根据接收的字节数收缩了缓冲区的大小,因此投递接收请求时,恢复缓冲区大小
e.SetBuffer(0, bufferSize);
if (!s.ReceiveAsync(e)) //投递接收请求
{
// 同步接收时处理接收完成事件
this.ProcessReceive(e);
}
}
else
{
this.ProcessError(e);
}
}

/// <summary>
/// 群发指令事件
/// </summary>
internal string SendAllClient()
{
int cnt = 0;
for (Int32 i = 0; i < this.numConnections; i++)
{
SocketAsyncEventArgs e = ioContextPool.pool[i];
// 检查当前活动的连接
if (e.UserToken != null)
{
try {
if ((e.UserToken as System.Net.Sockets.Socket).Available == 0)
{
//向指定连接发送指令
byte[] bty = new byte[12] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x08 };
this.SendToClient(e, bty);
}
}
catch(Exception ex)
{
}
}
}
return cnt.ToString();
}

/// <summary>
/// 向客户端发送信息
/// </summary>
private void SendToClient(SocketAsyncEventArgs e, byte[] btyArray)
{
if (e.SocketError == SocketError.Success)
{
Socket s = (Socket)e.UserToken;
//判断所有需接收的数据是否已经完成
if (s.Available == 0)
{
// 设置发送数据
Array.Copy(btyArray, 0, e.Buffer, 0, btyArray.Length);
//****此处报错******<现在已经正在使用此 SocketAsyncEventArgs 实例进行异步套接字操作>
e.SetBuffer(e.Offset, btyArray.Length);
if (!s.SendAsync(e)) //投递发送请求,这个函数有可能同步发送出去,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
{
// 同步发送时处理发送完成事件
this.ProcessSend(e);
}
}
else if (!s.ReceiveAsync(e)) //为接收下一段数据,投递接收请求,这个函数有可能同步完成,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
{
// 同步接收时处理接收完成事件
this.ProcessReceive(e);
}
}
else
{
this.ProcessError(e);
}
}
#endregion




...全文
914 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
蔓延 2017-09-21
  • 打赏
  • 举报
回复
求楼主帮忙,发布这个问题的解决办法
wy504903657 2016-07-02
  • 打赏
  • 举报
回复
请问楼主解决了吗 我也遇到同样的问题 急死了 不会解决
季雨林 2016-01-22
  • 打赏
  • 举报
回复
不是原来的操作线程不能直接发送,我是另外获取socket对象发送的
tcmakebest 2015-06-08
  • 打赏
  • 举报
回复
发送,接收,接收连接的 SocketAsyncEventArgs 都不能共用,要专用。

110,539

社区成员

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

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

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