现在的位置: 首页 > 综合 > 正文

大并发服务器不得不说的技术–connect 异步

2013年09月11日 ⁄ 综合 ⁄ 共 1026字 ⁄ 字号 评论关闭

前面我们谈的大多是服务端与客户端的技术,服务器开发其实有时还会涉及到跨服务器的访问,比如腾讯的拍拍服务器需要知道登录的会员信息,

就需要访问会员服务器。

跨务器访问会涉及到很多的技术,比如访问权限控制,数据同步等,这里主要来学习一下传输层。

为了更容易理解,我们将访问端服务器称为客户端,被访问端服务器称为服务端。

客户端发起一个连接的过程:

socket_fd = socket( AF_INET,SOCK_STREAM,0 );
ret = connect( socket_fd, (sockaddr*)&addr, sizeof(addr) );

问题就出在第二步,connect 如果是同步的,如果服务端很忙,客户端就会一直阻塞在这里,最多有可能会耗上几十秒,开玩笑,不会吧,客户端也是个服务器唉,

敢情这块不就成了瓶颈吗。

我们来理清下思路:

就像你跟人家姑娘表白了,姑娘说今天不告诉你答案,明天打电话再告诉你,你是不是要一直不吃不喝在她家楼下等呢,还是回去好好休息等她电话。

够明白了么,我建议还是回家休息去吧,因为你还有很多很重要的事做呢。

同样的思路,客户端需要想办法把这个差事放进某个通知队列中。

解决这个问题就是在connect 前先要将 socket_fd 设为异步的(nonblocking):

 

fcntl(socket_fd, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);

连接的时候如果暂时连不上,connect 返回-1,好家伙,人家姑娘害羞呢,但又不表示拒绝。

那行吧,在家等电话,先要把人家姑娘号码存起来吧。

在咱们这里就是将 socket_fd 放到通知队列中,以epoll 为例, 

struct epoll_event ee;
ee.events = EPOLLOUT | EPOLLET;
ee.data.fd = socket_fd;
epoll_ctl( epfd,  EPOLL_CTL_ADD, socket_fd,  &ee );

现在该干什么干什么去吧。

电话来了, 再做相应处理,应该高兴还是悲伤,表情函数预备下,免得到时大脑真空。

不同的是如果姑娘告诉你她答应你了事情就算完了,而epoll 回调告诉你有事件了你还需要确认一下:

getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
if( !error )
{
//OK
}

或者也可以使用 getsockname或getpeername,确认OK了才表示连接成功了。

抱歉!评论已关闭.