网站建设创业,wordpress 不发送邮件,怎样给公司产品做网站,百度站长工具fcntl函数提供了与网络编程相关的如下特性#xff1a;非阻塞式I/O。 通过使用F_SETFL命令设置O_NONBLOCK文件状态标志#xff0c;我们可以把一个套接字设置为非阻塞型。信号驱动式I/O。 通过使用F_SETFL命令设置O_ASYNC文件状态标志#xff0c;我们可以把一个套接字设置成O… 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_familyAF_INET; server_sockaddr.sin_porthtons(SERVPORT); server_sockaddr.sin_addr.s_addrINADDR_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((flagsfcntl( sockfd, F_GETFL, 0))0) perror(fcntl F_GETFL); flags | O_NONBLOCK; if(fcntl( sockfd, F_SETFL,flags)0) perror(fcntl); while(1){ sin_sizesizeof(struct sockaddr_in); if((client_fdaccept(sockfd,(struct sockaddr*)client_sockaddr,sin_size))-1){ //服务器接受客户端的请求返回一个新的文件描述符 perror(accept); exit(1); } if((recvbytesrecv(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*/
} 运行结果huangchengubuntu:~$ ./a.out
socket success!,sockfd3
bind success!
listening....
accept: Resource temporarily unavailable可以看到当accept的资源不可用时程序会自动返回。若将54--58行代码替换为if((flagsfcntl( sockfd, F_SETFL, 0))0) perror(fcntl F_SETFL);
flags | O_ASYNC;
if(fcntl( sockfd, F_SETFL,flags)0) perror(fcntl); 运行结果如下huangchengubuntu:~$ ./a.out
socket success!,sockfd3
bind success!
listening....可以看到进程一直处于等待中直到另一相关信号驱动它为止。由select函数实现的示例代码#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
#define SERVPORT 3333
#define BACKLOG 10
#define MAXDATASIZE 100
int main()
{ struct sockaddr_in server_sockaddr,client_sockaddr; int sin_size,recvbytes; fd_set readfd; fd_set writefd; 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_familyAF_INET; server_sockaddr.sin_porthtons(SERVPORT); server_sockaddr.sin_addr.s_addrINADDR_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);
/*select*/ FD_ZERO(readfd); // 将readfd 清空 FD_SET(sockfd,readfd); //将sockfd加入到readfd集合中 while(1){ sin_sizesizeof(struct sockaddr_in);int max_fd sockfd 1; if(select(max_fd,readfd,NULL,NULL,(struct timeval *)0)0){ //第一个参数是0和sockfd的最大值加1第二个参数是读集第三、四个参数是写集 //和异常集 if(FD_ISSET(sockfd,readfd)0){ // FD_ISSET 这个宏判断 sockfd 是否属于可读的文件描述符。从 sockfd 中读入, 输出到标准输出上去. if((client_fdaccept(sockfd,(struct sockaddr *)client_sockaddr,sin_size))-1){ //client_sockaddr客户端地址 perror(accept); exit(1); } if((recvbytesrecv(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); }/*select*/ }/*while*/
} 运行结果huangchengubuntu:~$ ./a.out
socket success!,sockfd3
bind success!
listening....转载于:https://www.cnblogs.com/wangfengju/p/6172570.html