UNP函数笔记十四: 带外数据

本文介绍如何使用TCP协议处理带外数据(OOB),包括发送和接收带外数据的方法、利用信号处理机制实现心跳监测等高级应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二十四章  带外数据:

#include <sys/socket.h>
int sockatmark(int sockfd);
    have oob mark return 1, have not oob mark return 0, error return -1

示例:

#include <sys/ioctl.h>

int 
sockatmark(int fd)
{
    int        flag;

    if (ioctl(fd, SIOCATMARK, &flag) == -1) {
        return(-1);
    }
    return(flag != 0);
}
#include "err_exit.h"
#include "tcp_connect.h"

int 
main(int argc, char ** argv)
{
    int sockfd;

    if (argc != 3) {
        printf("usage: tcpsend01 <host> <port#>\n");
        exit(1);
    }

    sockfd = tcp_connect(argv[1], argv[2]);

    if (write(sockfd, "123", 3) != 3) {
        err_exit("write error");
    }
    printf("wrote 3 bytes of normal data\n");
    sleep(1);

    if (send(sockfd, "4", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");
    sleep(1);

    if (write(sockfd, "56", 2) != 2) {
        err_exit("write error");
    }
    printf("wrote 2 bytes of normal data\n");
    sleep(1);

    if (send(sockfd, "7", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");
    sleep(1);

    if (write(sockfd, "89", 2) != 2) {
        err_exit("write error");
    }
    printf("wrote 2 bytes of normal data\n");
    sleep(1);

    exit(0);
}
#include <fcntl.h>

#include "err_exit.h"
#include "my_signal.h"
#include "tcp_listen.h"

int listenfd;
int connfd;

void 
sig_urg(int signo)
{
    int   n;
    char  buff[100];

    printf("SIGURG received\n");
    if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
        err_exit("recv error");
    }
    buff[n] = 0;  /* null terminate */
    printf("read %d OOB byte: %s\n", n, buff);
}

int 
main(int argc, char ** argv)
{
    int   n;
    char  buff[100];

    if (argc == 2) {
        listenfd = tcp_listen(NULL, argv[1], NULL);
    }
    else if (argc == 3) {
        listenfd = tcp_listen(argv[1], argv[2], NULL);
    }
    else {
        printf("usage: tcprecv01 [ <host> ] <port#>\n");
    }

    if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
        err_exit("accept error");
    }

    if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
        err_exit("my_signal error");
    }
    if (fcntl(connfd, F_SETOWN, getpid()) == -1) {
        err_exit("fcntl error");
    }

    for ( ; ; ) {
        if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
            err_exit("read error");
        }
        else if (n == 0) {
            printf("received EOF\n");
            exit(0);
        }
        buff[n] = 0;  /* null terminate */
        printf("read %d bytes: %s\n", n, buff);
    }
}
#include "err_exit.h"
#include "tcp_listen.h"

int 
main(int argc, char ** argv)
{
    int     listenfd;
    int     connfd;
    int     n;
    int     justreadoob = 0;
    char    buff[100];
    fd_set  rset;
    fd_set  xset;

    if (argc == 2) {
        listenfd = tcp_listen(NULL, argv[1], NULL);
    }
    else if (argc == 3) {
        listenfd = tcp_listen(argv[1], argv[2], NULL);
    }
    else {
        printf("usage: tcprecv02 [ <host> ] <port#>\n");
        exit(1);
    }

    if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
        err_exit("accept error");
    }

    FD_ZERO(&rset);
    FD_ZERO(&xset);
    for ( ; ; ) {
        FD_SET(connfd, &rset);
        if (justreadoob == 0) {
            FD_SET(connfd, &xset);
        }

        if (select(connfd + 1, &rset, NULL, &xset, NULL) == -1) {
            err_exit("select error");
        }

        if (FD_ISSET(connfd, &xset)) {
            if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
                err_exit("recv error");
            }
            buff[n] = 0;  /* null terminate */
            printf("read %d OOB byte: %s\n", n, buff);
            justreadoob = 1;
            FD_CLR(connfd, &xset);
        }

        if (FD_ISSET(connfd, &rset)) {
            if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
                err_exit("read error");
            }
            else if (n == 0) {
                printf("received EOF\n");
                exit(0);
            }
            buff[n] = 0;  /* null terminate */
            printf("read %d bytes: %s\n", n, buff);
            justreadoob = 0;
        }
    }
}

#include "err_exit.h"
#include "tcp_listen.h"

int 
main(int argc, char ** argv)
{
    int   listenfd;
    int   connfd;
    int   n;
    int   on = 1;
    char  buff[100];

    if (argc == 2) {
        listenfd = tcp_listen(NULL, argv[1], NULL);
    }
    else if (argc == 3) {
        listenfd = tcp_listen(argv[1], argv[2], NULL);
    }
    else {
        printf("usage: tcprecv02 [ <host> ] <port#>\n");
        exit(1);
    }

    if (setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) == -1) {
        err_exit("setsockopt error");
    }

    if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
        err_exit("accept error");
    }
    sleep(5);

    for ( ; ; ) {
        if ((n = sockatmark(connfd)) == -1) {
            err_exit("sockatmark error");
        }
        else if (n == 1) {
            printf("at OOB mark\n");
        }

        if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
            err_exit("read error");
        }
        else if (n == 0) {
            printf("received EOF\n");
            exit(0);
        }
        buff[n] = 0;  /* null terminate */
        printf("read %d bytes: %s\n", n, buff);
    }
}
#include "err_exit.h"
#include "tcp_connect.h"

int 
main(int argc, char ** argv)
{
    int sockfd;

    if (argc != 3) {
        printf("usage: tcpsend01 <host> <port#>\n");
        exit(1);
    }

    sockfd = tcp_connect(argv[1], argv[2]);

    if (write(sockfd, "123", 3) != 3) {
        err_exit("write error");
    }
    printf("wrote 3 bytes of normal data\n");

    if (send(sockfd, "4", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");

    if (write(sockfd, "5", 1) != 1) {
        err_exit("write error");
    }
    printf("wrote 1 bytes of normal data\n");

    exit(0);
}
#include "err_exit.h"
#include "tcp_connect.h"

int 
main(int argc, char ** argv)
{
    int sockfd;

    if (argc != 3) {
        printf("usage: tcpsend01 <host> <port#>\n");
        exit(1);
    }

    sockfd = tcp_connect(argv[1], argv[2]);

    if (write(sockfd, "123", 3) != 3) {
        err_exit("write error");
    }
    printf("wrote 3 bytes of normal data\n");
    sleep(1);

    if (send(sockfd, "4", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");
    sleep(1);

    if (write(sockfd, "5", 1) != 1) {
        err_exit("write error");
    }
    printf("wrote 1 bytes of normal data\n");
    sleep(1);

    if (send(sockfd, "6", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");
    sleep(1);

    if (write(sockfd, "7", 1) != 1) {
        err_exit("write error");
    }
    printf("wrote 1 bytes of normal data\n");
    sleep(1);

    exit(0);
}

#include <fcntl.h>

#include "err_exit.h"
#include "my_signal.h"
#include "tcp_listen.h"

int listenfd;
int connfd;

void 
sig_urg(int signo)
{
    int   n;
    char  buff[2048];

    printf("SIGURG received\n");
    if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
        err_exit("recv error");
    }
    buff[n] = 0;  /* null terminate */
    printf("read %d OOB byte: %s\n", n, buff);
}

int 
main(int argc, char ** argv)
{
    int size = 4096;

    if (argc == 2) {
        listenfd = tcp_listen(NULL, argv[1], NULL);
    }
    else if (argc == 3) {
        listenfd = tcp_listen(argv[1], argv[2], NULL);
    }
    else {
        printf("usage: tcprecv01 [ <host> ] <port#>\n");
    }

    if (setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &size, 
                   sizeof(size)) == -1) {
        err_exit("setsockopt error");
    }

    if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
        err_exit("accept error");
    }

    if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
        err_exit("my_signal error");
    }
    if (fcntl(connfd, F_SETOWN, getpid()) == -1) {
        err_exit("fcntl error");
    }

    for ( ; ; ) {
        pause();
    }
}
#include "err_exit.h"
#include "tcp_connect.h"

int 
main(int argc, char ** argv)
{
    int   sockfd;
    int   size;
    char  buff[16384];

    if (argc != 3) {
        printf("usage: tcpsend01 <host> <port#>\n");
        exit(1);
    }

    sockfd = tcp_connect(argv[1], argv[2]);

    size = 32768;
    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1) {
        err_exit("setsockopt error");
    }

    if (write(sockfd, buff, 16384) != 16384) {
        err_exit("write error");
    }
    printf("wrote 16384 bytes of normal data\n");
    sleep(5);

    if (send(sockfd, "a", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    printf("wrote 1 byte of OOB data\n");

    if (write(sockfd, buff, 1024) != 1024) {
        err_exit("write error");
    }
    printf("wrote 1024 bytes of normal data\n");

    exit(0);
}

#include <fcntl.h>
#include <sys/socket.h>

#include "err_exit.h"
#include "my_signal.h"

static int  servfd;
static int  nsec;         /* seconds betweeen each alarm */
static int  maxnprobes;   /* probes w/no response before quit */
static int  nprobes;      /* probes since last server response */

void 
sig_urg(int signo)
{
    int   n;
    char  c;
 
    if ((n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
        if (errno != EWOULDBLOCK) {
            err_exit("recv error");
        }
    }
    nprobes = 0;  /* reset counter */
    return;  /* may interrupt client code */
}

void 
sig_alrm(int signo)
{
    if (++nprobes > maxnprobes) {
        fprintf(stderr, "server is unreachable\n");
        exit(0);
    }
    if (send(servfd, "1", 1, MSG_OOB) != 1) {
        err_exit("send error");
    }
    alarm(nsec);
    return;  /* may interrupt client code */
}

void 
heartbeat_cli(int servfd_arg, int nsec_arg, int maxnprobes_arg)
{
    servfd = servfd_arg;  /* set globals for signal handlers */
    if ((nsec = nsec_arg) < 1) {
        nsec = 1;
    }
    if ((maxnprobes = maxnprobes_arg) < nsec) {
        maxnprobes = nsec;
    }
    nprobes = 0;

    if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
        err_exit("my_signal error");
    }
    if (fcntl(servfd, F_SETOWN, getpid()) == -1) {
        err_exit("fcntl error");
    }

    if (my_signal(SIGALRM, sig_alrm) == SIG_ERR) {
        err_exit("my_signal error");
    }
    alarm(nsec);
}
#include <fcntl.h>
#include <sys/socket.h>

#include "err_exit.h"
#include "my_signal.h"

static int  servfd;
static int  nsec;        /* seconds between each alarm */
static int  maxnalarms;  /* alarms w/no client probe before quit */
static int  nprobes;     /* alarms since last client probe */

void 
sig_urg(int signo)
{
    int   n;
    char  c;

    if ((n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
        if (errno != EWOULDBLOCK) {
            err_exit("recv error");
        }
    }
    if (send(servfd, &c, 1, MSG_OOB) != 1) {  /* echo back out-of-band byte */
        err_exit("send error");
    }

    nprobes = 0;  /* reset counter */
    return;  /* may interrupt server code */
}

void 
sig_alrm(int signo)
{
    if (++nprobes > maxnalarms) {
        printf("no probes from client\n");
        exit(0);
    }
    alarm(nsec);
    return;  /* may interrupt server code */
}

void
heartbeat_serv(int servfd_arg, int nsec_arg, int maxnalarms_arg)
{
    servfd = servfd_arg;  /* set globals for signal handlers */
    if ((nsec = nsec_arg) < 1) {
        nsec = 1;
    }
    if ((maxnalarms = maxnalarms_arg) < nsec) {
        maxnalarms = nsec;
    }
    nprobes = 0;

    if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
        err_exit("my_signal error");
    }
    if (fcntl(servfd, F_SETOWN, getpid()) == -1) {
        err_exit("fcntl error");
    }

    if (my_signal(SIGALRM, sig_alrm) == SIG_ERR) {
        err_exit("my_signal error");
    }
    alarm(nsec);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值