linux socket 阻塞服务端 非阻塞客户端,linux下异步RPC的阶段性总结-非阻塞SOCKET客户端...

尽可能使用非阻塞socket

int flags, s;

flags = fcntl (fd, F_GETFL, 0);

if (flags == -1){

close(fd);

return -1;

}

flags |= O_NONBLOCK;

s = fcntl (fd, F_SETFL, flags);

if (s == -1){

close(fd);

return -1;

}

使用效率高效的epoll机制获取多个socket上的IN/OUT事件

非阻塞socket连接服务端时,不一定立即连接得上服务器

通过判断connect函数的返回值和错误号做进一步跟踪

int ret = ::connect(this->fd, (struct sockaddr*)&(server_addr), sizeof(server_addr));

if(ret == 0){

this->on_connected();

}else if(ret < 0 && errno != EINPROGRESS){

//error

}else{

on_connecting();

}

IN/OUT事件时如果是connecting需要判断socket状态,socket reset发生时也会产生事件,然后才进入有效的读写

if(this->connect_status == 1){//connecting

int status = 0;

socklen_t slen;

if(getsockopt(this->fd, SOL_SOCKET, SO_ERROR, (void*)&status, &slen) < 0){

this->on_epollhup();

return;

}

if(status != 0){

this->on_epollhup();

return;

}

on_connected();

}

读写发生错误时,通过错误码判断是错误还是数据读完或者缓冲区满了,发生错误则按socket断开处理

错误代码包括:SIGPIP, EAGAIN 等, EAGAIN表示读完或者缓冲区满,等待下一次事件处理读或者写

为了达到更高的性能,epoll使用EPOLLET(边沿触发)机制,但是如果事件发生时,无数据可写时,下一次有数据时

则不会发生OUT事件,因此可以记录一个写空转标识write_nil_loop,epoll_wait事件之前判断是否有数据发送并且发生write_nil_loop,如果有,则重新登记epoll事件

if(worker->is_write_nil_loop() && (events & EPOLLOUT)){

epoll->remove(worker);

epoll->add(worker, events);

}else if(worker->get_events_mask() != events){

epoll->modify(worker, events);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值