当前位置:网站首页>2022-7-6 使用SIGURG来接受外带数据,不知道为什么打印不出来

2022-7-6 使用SIGURG来接受外带数据,不知道为什么打印不出来

2022-07-07 11:36:00 weixin_51187533

发送数据的端

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
int main(void){
    
    struct sockaddr_in server_address;
    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr.s_addr);
    server_address.sin_port = htons(9999);
    int sockfd = socket(PF_INET, SOCK_STREAM, 0);
    assert(sockfd >= 0);
    if(connect(sockfd, (struct sockaddr*)&server_address, sizeof(server_address)) < 0){
    
        perror("connect");
        printf("connection failed\n");
    }else {
    
        const char*oob_data = "abc";
        const char*normal_data = "123";
        send(sockfd, normal_data, strlen(normal_data), 0);
        send(sockfd, oob_data, strlen(oob_data), MSG_OOB);
        send(sockfd, normal_data, strlen(normal_data), 0);
    }
    close(sockfd);
    return 0;
}

接受数据端

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
#include<signal.h>
#include<fcntl.h>
#define BUF_SIZE 1024
static int connfd;

void sig_urg(int sig){
    
    /*如果系统调用或库函数正确执行的话, *errno的值是不会被清零(置0,注意这里是不会被清零, *不是不会被改变)的,假若执行函数A的时候发生了错误errno被改变, *接下来直接执行函数B,如果函数B正确执行的话, *errno还保留函数A发生错误时被设置的值。 */
   //保留原来的errno可以保证函数的可以重入性

   /* “可重入(reentrant)函数可以由多于一个任务并发使用, 而不必担心数据错误。可重入函数可以在任意时刻被中断, 稍后再继续运行,不会丢失数据;可重入函数要么使用本地变量, 要么在使用全局变量时保护自己的数据。” */
    int save_errno = errno;
    char buffer[BUF_SIZE];
    memset(buffer, '\0', BUF_SIZE);
    //接收外带数据
    int ret = recv(connfd, buffer, BUF_SIZE, MSG_OOB);
    printf("got %d bytes of oob data '%s'\n", ret, buffer);
    errno = save_errno;
}

void addsig(int sig, void(*sig_handler)(int)){
    
    //
    struct sigaction sa;
    memset(&sa, '\0', sizeof(sa));
    //定义信号处理函数
    sa.sa_handler = sig_handler;
    
    //设置收到信号的行为
    sa.sa_flags |= SA_RESTART;
    //自动重启由信号处理器程序中断的系统调用

    //sigfillset用于初始化一个信号集
    //利用sa_mask字段可指定一组信号,不允许它们中断此处理器程序的执行
    sigfillset(&sa.sa_mask);
    //对同一个信号的中断不会被递归的调用
    //可能需要重复看看牛客的信号讲解
    assert(sigaction(sig, &sa, NULL) != -1);
}

int main(void){
    

    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    //inet_pton(AF_INET, "127.0.0.1", &address.sin_addr.s_addr);
    address.sin_port = htons(9999);

    int sock = socket(PF_INET, SOCK_STREAM, 0);
    assert(sock >= 0);
    int ret = bind(sock, (struct sockaddr*)& address, sizeof(address));
    assert(ret != -1);
    ret = listen(sock, 5);
    assert(ret != -1);

    struct sockaddr_in client;
    socklen_t client_addrlength = sizeof(client);
    connfd = accept(sock, (struct sockaddr*)& client, &client_addrlength);

    if (connfd < 0){
    
        perror("accept");
    }else{
    
        //加到信号处理集合当中
        //其中信号处理函数sig_urg用来打印外带数据
        addsig(SIGURG, sig_urg);

        fcntl(connfd, F_SETOWN, getpid());
        char buffer[BUF_SIZE];
        //接收普通数据
        while (1){
    
            memset(buffer, '\0', BUF_SIZE);
            ret = recv(connfd, buffer, BUF_SIZE-1, 0);
            if (ret <= 0){
    
                break;
            }
            printf("got %d bytes of normal data '%s'\n", ret, buffer);
        }
        close(connfd);
    }
    close(sock);
    return 0;
}

在这里插入图片描述

原网站

版权声明
本文为[weixin_51187533]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_51187533/article/details/125643117