信号驱动,超时接收

本文介绍了信号驱动IO模型在UDP协议服务器中的应用,包括信号驱动原理、设置属主和信号触发模式。接着,讨论了超时接收的原因,通过设置超时控制以解决阻塞等待问题,提供了使用select函数实现超时接收的方法,并举例说明如何在TCP服务器中设置超时接收属性。
摘要由CSDN通过智能技术生成

一、信号驱动。
1、信号驱动原理是什么?
就是使用了系统编程中信号的机制,首先让程序安装SIGIO的信号处理函数,通过监听文件描述符是否产生了SIGIO信号,我们就知道文件描述符有没有数据到达。如果有数据到达(小明这个客人来了),则系统就会产生了SIGIO信号(门铃响了),我们只需要在信号处理函数读取数据即可。

模型:

void fun(int sig)
{
    //读取sockfd的数据即可。
}

signal(SIGIO,fun);  -> 只要将来收到SIGIO这个信号,就执行fun这个函数
sockfd   -> 只要有数据到达sockfd,就会产生一个SIGIO的信号

2、 信号驱动特点以及步骤。
特点: 适用于UDP协议,不适用于TCP协议。

步骤一: 由于不知道数据什么时候会到达,所以需要提前捕捉SIGIO信号。  -> signal()
步骤二: 设置套接字的属主,其实就是告诉这个套接字对应的进程ID是谁。 -> fcntl()
步骤三: 给套接字添加信号触发模式。                               -> fcntl()

1)如何设置属主?  -> fcntl()  -> man 2 fcntl

    #include <unistd.h>
        #include <fcntl.h>

       int fcntl(int fd, int cmd, ... /* arg */ );
    
    fd: 文件描述符
    cmd:  F_GETFL (void)  -> 获取文件属性
          F_SETFL (int)   -> 设置文件属性
          F_SETOWN (int)  -> 设置属性     -> 最后一个参数要填,填进程ID号,一般都是getpid()。

返回值:
    成功:文件描述符所有者
    失败:-1

例如: fcntl(sockfd,F_SETOWN,getpid());  -> 让sockfd与进程ID绑定在一起。

2)如何添加信号触发模式?   -> fcntl()  -> man 2 fcntl

int state;
state = fcntl(sockfd,F_GETFL);
state |= O_ASYNC;
fcntl(sockfd,F_SETFL,state);

  例题1: 使用信号驱动IO模型写一个UDP协议服务器,实现监听多个客户端给我发送过来的消息。

#include "head.h"

int sockfd;
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);

void func(int sig)
{
    //将sockfd中的数据读取出来。
    char buf[100];
    
    bzero(&cliaddr,sizeof(cliaddr));
    bzero(buf,sizeof(buf));
    recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&cliaddr,&len);
    
    printf("from cli:%s",buf);
    
}

int main(int argc,char *argv[]) //  ./server 50001
{
    //1. 创建UDP套接字
    sockfd = socket(AF_INET,SOCK_DGRAM,0);
    
    //2. 绑定IP地址
    struct sockaddr_in srvaddr;
    bzero(&srvaddr,sizeof(srvaddr));
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值