UNIX网络编程:fcntl函数

fcntl函数提供了与网络编程相关的如下特性:

非阻塞式I/O。  通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型。

信号驱动式I/O。 通过使用F_SETFL命令设置O_ASYNC文件状态标志,我们可以把一个套接字设置成O_ASYNC,一旦其状态发生变化,内核就产生一个SIGIO信号。

F_SETOWN命令允许我们指定用于接收SIGIO和SIGURG信号的套接字属主(进程ID或进程组ID)。其中SIGIO信号是套接字被设置为信号驱动式I/O型产生的,SIGURG信号是在新的带外数据到达套接字时产生的。F_GETOWN命令返回套接字的当前属主。

fcntl()函数有如下特性:

非阻塞I/O: 可将cmd 设为F_SETFL,将lock设为O_NONBLOCK。

信号驱动I/O:可将cmd设为F_SETFL,将lock设为O_ASYNC。

用以下方法将socket设置为非阻塞方式 :

int flags = fcntl(socket, F_GETFL, 0);
fcntl(socket, F_SETFL, flags | O_NONBLOCK);

将非阻塞的设置回阻塞可以用:

int flags = fcntl(socket, F_GETFL, 0);
fcntl(socket, F_SETFL, flags & ~O_NONBLOCK);

示例代码:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#define SERVPORT 3333
#define BACKLOG 10
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 100    

int main()
{
    struct sockaddr_in server_sockaddr,client_sockaddr;
    int sin_size,recvbytes,flags;
    int sockfd,client_fd;
    char buf[MAXDATASIZE];
/*创建socket*/
    if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){
        perror("socket");
        exit(1);
    }
    printf("socket success!,sockfd=%d\n",sockfd);    

/*设置sockaddr结构*/
    server_sockaddr.sin_family=AF_INET;
    server_sockaddr.sin_port=htons(SERVPORT);
    server_sockaddr.sin_addr.s_addr=INADDR_ANY;
    bzero(&(server_sockaddr.sin_zero),8);    

/*将本地ip地址绑定端口号*/
    if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1){
        perror("bind");
        exit(1);
    }
    printf("bind success!\n");    

/*监听*/
    if(listen(sockfd,BACKLOG)==-1){
        perror("listen");
        exit(1);
    }
    printf("listening....\n");    

/*fcntl()函数,处理多路复用I/O*/
    if((flags=fcntl( sockfd, F_GETFL, 0))<0)
            perror("fcntl F_GETFL");
    flags |= O_NONBLOCK;
    if(fcntl( sockfd, F_SETFL,flags)<0)
            perror("fcntl");
    while(1){
        sin_size=sizeof(struct sockaddr_in);
        if((client_fd=accept(sockfd,(struct sockaddr*)&client_sockaddr,&sin_size))==-1){  //服务器接受客户端的请求,返回一个新的文件描述符
            perror("accept");
            exit(1);
        }
        if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){
            perror("recv");
            exit(1);
        }
        if(read(client_fd,buf,MAXDATASIZE)<0){
            perror("read");
            exit(1);
        }
        printf("received a connection :%s",buf);    

    /*关闭连接*/
    close(client_fd);
    close(sockfd);
    exit(0);
    }/*while*/
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/unix/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索socket
, include
, 阻塞
, 套接字
, 信号
, nonblock
, fcntl ubuntu c
, fcntl
fcntl函数
,以便于您获取更多的相关知识。

时间: 2024-08-25 03:10:22

UNIX网络编程:fcntl函数的相关文章

select-调试信息无法打印 unix网络编程

问题描述 调试信息无法打印 unix网络编程 如代码注释信息所示,应该是缓冲区的问题,但是stderr是无缓冲区的,而且也使用了fflush函数,也没用.希望能有人指点指点,谢谢 #include "globle.h" #define port 8082 int main( int argc, char *argv[] ){ fprintf(stderr, "11111111111n");//无法打印 fflush(stdout); int listenfd,soc

UNIX网络编程之旅-配置unp.h头文件环境

最近在学习Unix网络编程(UNP),书中steven在处理网络编程时只用了一个#include "unp.h"  相当有个性并且也很便捷 于是我把第三版的源代码编译实现了这个过程,算是一种个性化的开发环境的搭建吧,顺便把过程记录下来,以便自己以后查阅.   首先去网上找到源代码包unpv.13e.tar.gz 一找一大堆 解压缩到你的某个目录,unpv13e里面大致有这些目录 ├── aclocal.m4 ├── advio ├── bcast ├── config.guess ├─

unix网络编程问题(初学者)

问题描述 unix网络编程问题(初学者) 除了头文件和打印外,我都是照着书敲的,但是结果不对,希望帮我解决,谢谢啦!!!书上的正确结果是一串表示时间的字符 问题:connect error 在建立服务器的连接出错输入:./get_tima 192.168.154.130(ip地址我用ifconfig得到的,我也用127.0.0.1做过一样得不到想要的结果)结果:connect errorread error 出处:unix网络编程 1.2-一个简单的时间获取客户程序 #include#inclu

网络编程-inet_pton函数运行时,这个函数执行出错,难道我的函数调用有问题吗

问题描述 inet_pton函数运行时,这个函数执行出错,难道我的函数调用有问题吗 #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<stdio.h> #include<stdlib.h> #include<strings.h> void outputError(char *message) { fprintf(stdout, &q

UNIX网络编程:I/O复用:select和poll函数

我们看到TCP客户同时处理两个输入:标准输入和TCP套接字.我们遇到的问题是就在客户阻塞于(标准输入上)fgets调用,服务器进程会被杀死.服务器TCP虽然正确的给客户TCP发送了一个FIN,但是既然客户进程正阻塞于从标准输入读入的过程,它将看不到这个EOF,直到从套接字读时为止(可能额已过了很长时间).这样的进程需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个I/O条件就绪(也就是说输入已准备好被读入,或者描述符已能承接更多的输出),它就通知进程.这个能力称为I/O复用,是由s

Unix网络编程 之 基本套接字调用(一)

       Unix/Linux支持伯克利风格的套接字编程,它同时支持面向连接和面向无连接类型的套接字.       套接字最常用的一些系统调用:       socket()             bind()       connect()       listen()       accept()       send()       recv()       sendto()       recvfrom()       close()       shutdown()       

Unix网络编程API

1.字节序函数 #include <netinet.h>uint16_t htons(uint16_t host16bitvalue);uint32_t htonl(uint32_t host32bitvalue); 返回:网络字节序值 uint16_t ntohs(uint16_t net16bitvalue);uint32_t ntohl(uint32_t net32bitvalue); 返回:主机字节序值 一个测试本机字节序的程序,可参见见unpv12e:intro/byteorder.

UNIX网络编程:UDP 中的外出接口的确定

已连接UDP套接字还可用来确定用于特定目的地的外出接口.这是由connect函数应用到UDP套接字时的一个副作用造成的:内核选择本地IP地址.这个本地IP地址通过为目的IP地址搜索路由表得到外出接口,然后选用该接口的主IP地址而选定. 注意:getsockname函数调用的位置. #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h>

UNIX网络编程:UDP缺乏流量控制(改进版)

现在我们查看无任何流量控制的UDP对数据报传输的影响.首先我们把dg_cli函数修改为发送固定数目的数据报,并不再从标准输入读.如下,它写2000个1400字节大小的UDP数据报给服务器. 客户端程序cli.c: #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #inc