libjingle开发(5)

2019-08-31 12:21

九、异步socket(asyncsocket)

异步发送数据以后不等对方确认,函数就退出了 同步则要等数据发完以后才能退出,运行下面的代码

以接收一条消息来说明这个问题。首先,程序向系统投递一个接收数据的请求,并为其指定一个数据缓冲区和回调函数,回调函数用来指示当数据到达后将如何处理,然后我们的程序继续执行下去,当有数据到达的时候,系统将数据读入缓冲区,并执行回调函数,处理这条消息。我们并不需要关心这条消息何时到达。

二、什么情况下我们用异步Socket:

有些人认为,异步Socket的性能比同步Socket的性能高很多,应该在各种环境下都用异步Socket,其实不然。在某些环境下面。异步反到比同步的性能低,那么在哪些情况下会这样呢?

1、 客户端Socket。

2、 服务端连接数比较少。

3、 连接数很多,但都是短连接。

在这些环境下,我们用同步Socket不但可以简化代码,而且性能并不会比异步Socket低。但在服务端连接比较多而且是长连接的情况下,我们就要使用异步Socket。

现在我们来看看如何用异步Socket编程。

首先,我们要建立一个Socket用来监听:

Socket _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPEndPoint localEP = new IPEndPoint(_address, _port); _listener.Bind(localEP); _listener.Listen(100);

然后创建一个线程来处理客户端连接请求:

Thread _acceptWorkThread = new Thread(AcceptWorkThread); _acceptWorkThread.Start();

private void AcceptWorkThread() {

while (_isListener)

{

UserInfo info = new UserInfo();//这个UserInfo是用来保存客户信息的。 info.socket = socket;

Socket socket = _listener.Accept(); //这里进行其它处理。

socket.BeginReceive(info.Buffer,

0,

info.Buffer.Length,

SocketFlags.None,

ReceiveCallBack, info);//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数 }

} 我们再来看看回调函数的定义:

private void ReceiveCallBack(IAsyncResult ar) {

UserInfo info = (UserInfo)ar.AsyncState; Socket handler = info.socket; int readCount = 0; try

{

readCount = handler.EndReceive(ar);//调用这个函数来结束本次接收并返回接收到的数据长度。 }

catch (SocketException)//出现Socket异常就关闭连接 {

CloseSocket(info);//这个函数用来关闭客户端连接

return; }

catch { }

if (readCount > 0) {

byte[] buffer = new byte[readCount];

Buffer.BlockCopy(info.Buffer, 0, buffer, 0, readCount); Analyzer(info, buffer);//这个函数用来处理接收到的信息。 try {

handler.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);//向系统投递下一个接收请求 }

catch (SocketException) //出现Socket异常就关闭连接 {

CloseSocket(info); } catch {

} }

else //如果接收到0字节的数据说明客户端关闭了Socket,那我们也要关闭Socket {

CloseSocket(info); }

}

接下来我们看看如何发送数据给客户端:

public void Send(Socket socket, byte message) { try

{

info.socket.BeginSend(message, 个回调函数。 }

catch (SocketException ex) {

CloseSocket(info); }

catch

0,

_byte.Length,

SocketFlags.None,

new

AsyncCallback(SendCallBack), info);//这里向系统投递一个发送数据的请求,并指定一

{

} }

定义发送回调函数:

private void SendCallBack(IAsyncResult ar) {

UserInfo info = (UserInfo)ar.AsyncState; try {

info.socket.EndSend(ar);//调用这个函数来结束本次发送。 } catch { } }

好了,整个监听、接收、发送的过程就完成了,很简单吧。现在需要说明的是,我在这里接收客户端连接的Accept是用的同步的,我个人认为在这里用同步的会比用异步好一些。因为这样代码简单而且没有性能上的损失。

Libjinlge 底层主要代码分析

一、socket(socket.h)

1.主要给出socket接口,该接口插槽实现各种网络,符合windows和unix标准。 2.socket接口中的主要函数: (大部分能通过函数名知道功能)

virtual SocketAddress GetLocalAddress() const = 0; virtual SocketAddress GetRemoteAddress() const = 0; virtual int Bind(const SocketAddress& addr) = 0; virtual int Connect(const SocketAddress& addr) = 0; virtual int Send(const void *pv, size_t cb) = 0;

virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) = 0; virtual int Recv(void *pv, size_t cb) = 0;

virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) = 0; virtual int Listen(int backlog) = 0;

virtual Socket *Accept(SocketAddress *paddr) = 0; virtual int Close() = 0;

virtual int GetError() const = 0;

virtual void SetError(int error) = 0;

inline bool IsBlocking() const { return IsBlockingError(GetError()); }

enum ConnState { CS_CLOSED, CS_CONNECTING, CS_CONNECTED };

virtual ConnState GetState() const = 0;

二、asyncsocket(asyncsocket.h)

1.asyncsocket接口继承自socket和sigslot::has_slots<>,主要给出异步socket接口所要发出和接收的信号。

2.asyncsocket接口中的信号

sigslot::signal1 SignalReadEvent; 读信号 sigslot::signal1 SignalWriteEvent; 写信号 sigslot::signal1 SignalConnectEvent; 连接信号 sigslot::signal2 SignalCloseEvent; 关闭信号

3. asyncsocketadapter 继承自asyncsocket,异步socket适配器主要用来绑定信号到事件,并指定一个回调函数来处理事件

4.asyncsocketadapter中的主要函数 绑定:

socket->SignalConnectEvent.connect(this, &AsyncSocketAdapter::OnConnectEvent); socket->SignalReadEvent.connect(this, &AsyncSocketAdapter::OnReadEvent); socket->SignalWriteEvent.connect(this, &AsyncSocketAdapter::OnWriteEvent);

socket->SignalCloseEvent.connect(this, &AsyncSocketAdapter::OnCloseEvent); 指定函数:

virtual void OnConnectEvent(AsyncSocket * socket) { SignalConnectEvent(this); } virtual void OnReadEvent(AsyncSocket * socket) { SignalReadEvent(this); } virtual void OnWriteEvent(AsyncSocket * socket) { SignalWriteEvent(this); }

virtual void OnCloseEvent(AsyncSocket * socket, int err) { SignalCloseEvent(this, err); }

三、asyncpacksocket(asyncpacksocket.h和asyncpacksocket.cpp)

1.封装数据包,实现数据包的不同步接收。实例化时要传入一个asyncskcket指针 2.主要函数:

要用到的套接字方法:

virtual SocketAddress GetLocalAddress() const; virtual SocketAddress GetRemoteAddress() const; virtual int Bind(const SocketAddress& addr); virtual int Connect(const SocketAddress& addr); virtual int Send(const void *pv, size_t cb);

virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr); virtual int Close();

virtual int SetOption(Socket::Option opt, int value);


libjingle开发(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:资产评估操作实施细则 - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: