c# socket异步通信的问题
是从MSDN的异步通信示例上改的。但客户端连接成功后,再发送数据,服务器就没响应了,因为在服务器监听到客户端连接后就进入异步接收状态,收到数据后就进入异步发送(发送消息到客户端)状态,然后就关闭(shutdown和close)了socket,因此当客户端在次发送数据时,服务器没响应。但是我改了半天,还是没能解决此问题,望高手指点 --------------------编程问答-------------------- 异步的完成最后,再次开异步接受数据。。。。。。。
你没看懂msdn的例子。网上这种例子和框架很多呢。 --------------------编程问答--------------------
--------------------编程问答-------------------- 学习! --------------------编程问答-------------------- 我这的异步接收函数是这样的
/// <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;
}
}
}
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());
}
}
补充:.NET技术 , C#