「已注销」 2023-10-27 09:06 采纳率: 62.5%
浏览 2

sigio进行通信时收不到客户端发来的消息程序没有报错但是我感觉流程没啥问题但是就是收不到发来的信号#include <sys,如何解决?

sigio进行通信时收不到客户端发来的消息
程序没有报错 但是我感觉流程没啥问题 但是就是收不到发来的信号

#include <sys/socket.h>
#include <csignal>
#include <netinet/in.h>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
using namespace std;

int fd;

void sigio(int sig){
    char buf[128];
    memset(buf , 0, 128);

    sockaddr_in addr;
    int addrlen;
    int len = recvfrom(fd, buf, 128, 0, (sockaddr*)&addr, (socklen_t*)&addrlen);
    cout<<"client :"<<buf<<endl;
    int slen = sendto(fd, buf, 128, 0, (sockaddr*)&addr, static_cast<socklen_t>(addrlen));
}

/*
 (1):进程的信号集合如何保存
    action[64] 每个信号对应不同的位置
 (2):如何把signal保存到进程里
    我们满足条件调用signal时 实际上是进行了SYSCALL_DEFINE2的调用 在SYSCALL_DEFINE2会调用do_sigaction 从而完成信号和其处理的关联
 (3):信号如何发送
     Sys_kill(进程号,发什么信号)
 */

int main(){
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    signal(SIGIO, sigio);

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.s_addr = INADDR_ANY;

    bind(fd, (sockaddr*)&addr, sizeof(addr));

    while (true) {
        sleep(1);
    }
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-27 13:28
    关注

    【以下回答由 GPT 生成】

    (1): 进程的信号集合如何保存? 要解决这个问题,我们需要了解信号集合的保存方式。通过分析问题代码,我们可以看到在 signal(SIGIO, sigio) 这行代码里,我们使用了 signal() 函数来将 SIGIO 信号和 sigio() 函数关联起来。但是在本代码中,我们并没有主动调用 sigiox() 函数来处理 SIGIO 信号。这就意味着我们需要在进程中保存一个信号集合,以便在相应的信号发生时可以调用对应的处理函数。

    在 Unix 系统中,基于进程的信号集合通过 sigaction 结构体来保存。该结构体包含了信号的处理函数等信息。

    (2): 如何将信号保存到进程中? 我们知道,要将信号保存到进程中,我们需要调用 sigaction() 函数来完成信号和其处理函数的关联。您可以按照以下步骤进行实现:

    Step 1: 导入头文件 <csignal>

    Step 2: 在 main() 函数前声明信号处理函数 sigio()

    Step 3: 在 main() 函数中创建并初始化一个 sigaction 结构体变量 sa

    Step 4: 将信号处理函数 sigio() 分配给 sasa_handler 成员变量。

    Step 5: 使用 sigemptyset() 函数初始化 sasa_mask 成员变量,以清空信号掩码。

    Step 6: 设置 sa 的其他成员变量,例如 sa_flags

    Step 7: 调用 sigaction() 函数,将信号和 sa 结构体关联起来。

    下面是优化后的代码实现示例:

    #include <sys/socket.h>
    #include <csignal>
    #include <netinet/in.h>
    #include <cstring>
    #include <iostream>
    #include <unistd.h>
    #include <fcntl.h>
    using namespace std;
    
    int fd;
    
    void sigio(int sig){
        char buf[128];
        memset(buf , 0, 128);
    
        sockaddr_in addr;
        socklen_t addrlen = sizeof(addr); // 必须初始化addr的长度
        int len = recvfrom(fd, buf, 128, 0, (sockaddr*)&addr, &addrlen);
        cout << "client: " << buf << endl;
        int slen = sendto(fd, buf, 128, 0, (sockaddr*)&addr, addrlen);
    }
    
    int main(){
        fd = socket(AF_INET, SOCK_DGRAM, 0);
    
        struct sigaction sa;
        sa.sa_handler = sigio;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
    
        sigaction(SIGIO, &sa, NULL);
    
        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(9999);
        addr.sin_addr.s_addr = INADDR_ANY;
    
        bind(fd, (sockaddr*)&addr, sizeof(addr));
    
        while (true) {
            sleep(1);
        }
    }
    

    (3): 信号如何发送? 对于信号的发送,我们可以使用 kill() 函数或者 raise() 函数。但是在本问题中,我们不需要发送信号给其他进程,所以我们不需要主动发送信号。

    综上所述,根据以上的解释和代码示例,我认为您可以尝试以下步骤来解决您的问题:

    1. 按照步骤 (2) 中的代码示例,更新您的代码中关于信号处理的部分,使用 sigaction() 将信号和处理函数关联起来。

    2. 确保在 sigio() 函数中正确地处理接收到的消息,并回复给客户端。

    3. 检查您的网络连接是否正常,确保客户端能够成功发送消息到服务器的指定端口。

    希望这些信息对您有所帮助,如果您还有其他问题或需要进一步的解释,请随时提问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月27日