c# socket异步通信的问题

weistar0622 2011-06-30 01:51:32
是从MSDN的异步通信示例上改的。
但客户端连接成功后,再发送数据,服务器就没响应了,因为在服务器监听到客户端连接后就进入异步接收状态,收到数据后就进入异步发送(发送消息到客户端)状态,然后就关闭(shutdown和close)了socket,因此当客户端在次发送数据时,服务器没响应。但是我改了半天,还是没能解决此问题,望高手指点
...全文
176 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
to_Boyka 2011-06-30
  • 打赏
  • 举报
回复
学习着...
weistar0622 2011-06-30
  • 打赏
  • 举报
回复
我这的异步接收函数是这样的
 private static void ReadCallback(IAsyncResult ar)
{
try
{
String content = String.Empty;

// 【从异步状态对象中获取状态对象进行socket操作】Retrieve the state object and the handler socket from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;


// 【从客户端socket读出数据】Read data from the client socket.
int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0)
{
// 【数据可能很大,持续累加保存接收到的数据】There might be more data, so store the data received so far.
state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

// 【如果没有检查文件末尾标签<EOF>,则继续读取数据】Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// 【将所有从客户端读出的数据显示到控制台上】All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
// 【回复客户端】Echo the data back to the client.
content = "[来自服务器的消息]:" + AnalyseData.Fun_GetReturnData(content);
Send(handler, content);//向客户端发送消息
}
else
{
// 【没有获取所有数据,继续获取】Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
}

}
catch (Exception Ex)
{
Console.WriteLine("方法 ReadCallback 异常:" + Ex.Message.ToString());
}
}
Nihn 2011-06-30
  • 打赏
  • 举报
回复
学习!
isjoe 2011-06-30
  • 打赏
  • 举报
回复

/// <summary>
/// 接受数据完成处理函数,异步的特性就体现在这个函数中,
/// 收到数据后,会自动解析为字符串报文
/// </summary>
/// <param name="iar">目标客户端Socket</param>
protected virtual void ReceiveData(IAsyncResult iar)
{
Socket client = (Socket)iar.AsyncState;

try
{
//如果两次开始了异步的接收,所以当客户端退出的时候
//会两次执行EndReceive

int recv = client.EndReceive(iar);

if (recv == 0)
{
//正常的关闭
CloseClient(client, Session.ExitType.NormalExit);
return;
}

string receivedData = _coder.GetEncodingString(_recvDataBuffer, recv);

//发布收到数据的事件
if (RecvData != null)
{
Session sendDataSession = FindSession(client);

Debug.Assert(sendDataSession != null);

//如果定义了报文的尾标记,需要处理报文的多种情况
if (_resolver != null)
{
if (sendDataSession.Datagram != null &&
sendDataSession.Datagram.Length != 0)
{
//加上最后一次通讯剩余的报文片断
receivedData = sendDataSession.Datagram + receivedData;
}

string[] recvDatagrams = _resolver.Resolve(ref receivedData);


foreach (string newDatagram in recvDatagrams)
{
//深拷贝,为了保持Datagram的对立性
ICloneable copySession = (ICloneable)sendDataSession;

Session clientSession = (Session)copySession.Clone();

clientSession.Datagram = newDatagram;
//发布一个报文消息
RecvData(this, new NetEventArgs(clientSession));
}

//剩余的代码片断,下次接收的时候使用
sendDataSession.Datagram = receivedData;

if (sendDataSession.Datagram.Length > MaxDatagramSize)
{
sendDataSession.Datagram = null;
}

}
//没有定义报文的尾标记,直接交给消息订阅者使用
else
{
ICloneable copySession = (ICloneable)sendDataSession;

Session clientSession = (Session)copySession.Clone();

clientSession.Datagram = receivedData;

RecvData(this, new NetEventArgs(clientSession));
}

}//end of if(RecvData!=null)

//********************继续接收来自来客户端的数据**********
client.BeginReceive(_recvDataBuffer, 0, _recvDataBuffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveData), client);

}
catch (SocketException ex)
{
//客户端退出
if (10054 == ex.ErrorCode)
{
//客户端强制关闭
CloseClient(client, Session.ExitType.ExceptionExit);
}

}
catch (ObjectDisposedException ex)
{
//这里的实现不够优雅
//当调用CloseSession()时,会结束数据接收,但是数据接收
//处理中会调用int recv = client.EndReceive(iar);
//就访问了CloseSession()已经处置的对象
//我想这样的实现方法也是无伤大雅的.
if (ex != null)
{
ex = null;
//DoNothing;
}
}

}
isjoe 2011-06-30
  • 打赏
  • 举报
回复
异步的完成最后,再次开异步接受数据。。。。。。。

你没看懂msdn的例子。网上这种例子和框架很多呢。

110,534

社区成员

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

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

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