C#中稳定的socket收发实现:agsxmpp的ClientSocket实现
来源:互联网 发布:长春网络营销策划 编辑:程序博客网 时间:2024/06/16 22:39
在xmpp协议中规定 从客户端到服务器端的通讯方式是一个持续的tcp连接或者是http的polling,后者作为备选,一般也是使用前者。
socket编程可简可难,可好可烂。在C#中,因为CLR维持了工作组线程,异步调用的语法也相对简单(好像是最简单的了-_-!),所以写出稳定的socket收发也变的更容易了。agsxmpp的ClientSocket实现大概可分步为:
1.一个 tcp连接
2.一个初始的连接异步调用
3.连接异步调用完成后接收异步调用开始,并且在完成的时候不断回调自身实现循环,但是这个循环不保证是在同一个线程内部的
4.发送异步调用在连接之后断开之前都可以进行
总之对接收而言是一个 socket 资源 两个 工作端 线程资源。在这里资源这个理解很重要,因为实际上每次接收线程回调后并不一定还是原来的线程继续执行接收方法。有可能,当发送方法不工作 ,而接收线程又未启动的话,实质上是没有 线程在对 socket做任何事情的。socket作为网络资源 与 线程作为 CPU 资源事实上是分离了。以前很难这样想问题,因为线程的开发相当复杂,而现在可以异步调用,交由工作线程来做。
以下是receive方法以及其完成回调,可以看到在EndReceive方法中判断是否结束如不是则回调Receive方法,循环下去。
/// <summary>
/// Read data from server.
/// </summary>
private void Receive()
{
m_NetworkStream.BeginRead(m_ReadBuffer, 0, BUFFERSIZE, new AsyncCallback(EndReceive), null);
}
private void EndReceive(IAsyncResult ar)
{
try
{
int nBytes;
nBytes = m_NetworkStream.EndRead(ar);
if( nBytes > 0 )
{
// uncompress Data if we are on a compressed socket
if (m_Compressed)
{
byte[] buf = Decompress(m_ReadBuffer, nBytes);
base.FireOnReceive(buf, buf.Length);
}
else
{
//Console.WriteLine("Socket OnReceive: " + System.Text.Encoding.UTF8.GetString(m_ReadBuffer, 0, nBytes));
// Raise the receive event
base.FireOnReceive(m_ReadBuffer, nBytes);
}
// Setup next Receive Callback
if (this.Connected) this.Receive();
}
else
{
Disconnect();
}
}
catch(ObjectDisposedException)
{
//object already disposed, just exit
return;
}
catch (System.IO.IOException ex)
{
Console.WriteLine("/nSocket Exception: " + ex.Message);
Disconnect();
}
}
Receive 方法 在 EndConnection方法结束的时候即开始回调:
private void EndConnect(IAsyncResult ar)
{
try
{
// pass connection status with event
_socket.EndConnect(ar);
m_Stream = new NetworkStream(_socket, false);
m_NetworkStream = m_Stream;
#if SSL || MONOSSL
if (m_SSL)
InitSSL();
#endif
FireOnConnect();
// Setup Receive Callback
this.Receive();
}
catch (Exception ex)
{
base.FireOnError(ex);
}
}
这个是send方法:
public override void Send(byte[] bData)
{
base.FireOnSend(bData, bData.Length);
//Console.WriteLine("Socket OnSend: " + System.Text.Encoding.UTF8.GetString(bData, 0, bData.Length));
// compress bytes if we are on a compressed socket
if (m_Compressed)
{
bData = Compress(bData);
}
// .NET 2.0 SSL Stream issues when sending multiple async packets
// http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=124213&SiteID=1
if (m_PendingSend)
m_SendQueue.Enqueue(bData);
else
{
m_PendingSend = true;
m_NetworkStream.BeginWrite(bData, 0, bData.Length, new AsyncCallback(EndSend), null);
}
}
- C#中稳定的socket收发实现:agsxmpp的ClientSocket实现
- C#实现消息的收发
- c#实现短期的收发
- 使用ClientSocket控件实现CSDN论坛帖子的自动回复
- 使用ClientSocket控件实现CSDN论坛帖子的自动回复
- Visual C# UDP协议的收发实现
- C# Socket的实现
- C# Socket的实现
- PowerBuilder 7.0中实现电子邮件的收发
- PHP 通过Socket收发十六进制数据的实现代码
- 基于TCP协议的socket通讯实现收发消息
- agsXMPP 实现原理
- 使用ClientSocket控件实现CSDN论坛帖子的自动回复(修改)
- Pyhont 收发mail的实现
- 串口异步收发的实现
- Silverlight Socket 实现收发信息
- Silverlight Socket 实现收发信息
- Silverlight Socket 实现收发信息
- 谈谈C#中的事件注册和注销
- C#+Windows API操纵系统菜单
- c#实现google样式的分页
- ASP.NET 2.0 中的代码隐藏和编译
- C#中简单实现多线程
- C#中稳定的socket收发实现:agsxmpp的ClientSocket实现
- 转载-Oracle数据库的导出和导入
- 编译原理课程设计---用java写的SNLCompiler(简单嵌套语言SNL的编译程序)
- 函数的参数最好采用引用方式读入
- HTTP/1.1 的连接分析
- 关于变形的背包问题的答案(C版)
- 买书,工资,臭脚丫
- S60中文模拟器的问题
- Makefile Howto [转贴]