Linux多线程服务器端编程笔记一

最近在阅读陈硕先生的《Linux多线程服务器端编程》,学习了一些socket接口的新用法,在这里做一下笔记。

一步创建非阻塞socket

socket函数原型如下:

int socket(int domain, int type, int protocol);

自从Linux-2.6.27后,type参数除了可以传递诸如SOCK_STREAM、SOCK_DGRAM等标志外,还可以传递SOCK_NONBLOCK、SOCK_CLOEXEC。SOCK_NONBLOCK设置新创建的文件描述符为非阻塞;设置SOCK_CLOEXEC标志后,程序执行execl系列函数后,文件描述符将被关闭,不能再使用,但是执行fork调用后,文件描述符被子进程继承,在子进程中仍然可以使用。有了这两个标志后,可以使用socket一步创建非阻塞的socket,比如创建一个非阻塞的TCP socket:

int sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NOBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);
if (sockfd < 0)
{
    perror("socket error")
}


accept4一步得到非阻塞socket

accept4在accept的基础上增加了flag参数,可以用来传递SOCK_NONBLOCK和SOCK_CLOEXEC。这样就可以让accept4直接返回非阻塞的连接描述符。

int connfd = accept4(sockfd, (struct sockaddr *)&addr, &addrlen, SOCK_NOBLOCK | SOCK_CLOEXEC);
if (connfd < 0)
{
    perror("accept4 error");
}

设置文件描述符为非阻塞

  // non-block
int flags = fcntl(sockfd, F_GETFL, 0);
flags |= O_NONBLOCK;
int ret = fcntl(sockfd, F_SETFL, flags);
if (ret < 0)
{
    perror("fcntl O_NOBLOCK error");
}
// close-on-exec
flags = fcntl(sockfd, F_GETFD, 0);
flags |= FD_CLOEXEC;
ret = fcntl(sockfd, F_SETFD, flags);
if (ret < 0)
{
    perror("fcntl FD_CLOEXEC");
}

这是传统获得非阻塞socket的方式,先通过socket和accept接口获得阻塞的socket,然后调用fcntl设置非阻塞标志。需要注意一点就是,设置前需要先获取以前的标志,然后把新标志添加进去,否则会把以前的标志清除,这自然会导致悲剧。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值