• TCP带外数据


    简单说明

    TCP带外数据也称为紧急模式, 常用于中断某些操作, 如中断ftp文件的传输.
    调用系统函数时我们需要处理一些信号操作, 而TCP带外数据可理解为由本地向对端发送一个signal, 让对端能采取相应的处理措施.
    接收到带外数据时, 系统会产生SIGURG信号.
    TCP带外数据就是一个普通的字节, 只是在TCP头部特别注明在哪个位置的字节是带外数据而已.

    TCP带外数据的格式要求:

    • 每个连接只有一个TCP带外数据
    • 每个连接只有一个带外标记
    • 每个连接只有一个单字节的带外缓冲区

    通俗的讲就是在TCP接受缓冲区内一次只能有一个带外数据存在, 不能同时存在二个或多个, 且每个带外数据只有一个字节

    简单发送与接受

    send.c

    注意send(sockfd,"444",3,MSG_OOB), 虽然发送了三个字节的紧张数据, 实际有效的只有一位

    #include <stdio.h>
    #include <assert.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <strings.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    
    #define SERV_PORT 5555
    
    int tcp_connect(){
        struct sockaddr_in serv;
        int sockfd;
    
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        assert(sockfd);
        bzero(&serv,sizeof(serv));
        serv.sin_family=AF_INET;
        serv.sin_port=htons(SERV_PORT);
        serv.sin_addr.s_addr=inet_addr("127.0.0.1");
    
        assert(connect(sockfd,(struct sockaddr *)&serv,sizeof(serv)) == 0);
        return sockfd;
    }
    
    int main(int argc, char *argv[]) {
        int sockfd=tcp_connect();
        write(sockfd,"123",3);
        printf("wrote 3 bytes of normal data
    ");
        sleep(1);
    
        send(sockfd,"444",3,MSG_OOB);
        printf("wrote 3 byte of OOB data
    ");
        sleep(1);
    
        write(sockfd,"56",2);
        printf("wrote 2 bytes of normal data
    ");
        sleep(1);
    
        send(sockfd,"7",1,MSG_OOB);
        printf("wrote 1 byte of OOB data
    ");
        sleep(1);
    
        write(sockfd,"89",2);
        printf("wrote 2 bytes of normal data
    ");
        sleep(1);
    
        return 0;
        return 0;
    }
    

    recv.c

    通过设置fcntl来请求系统将SIGURG信号发送给指定进程

    #include <stdio.h>
    #include <fcntl.h>
    #include <signal.h>
    #include <assert.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <strings.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    
    #define SERV_PORT 5555
    
    int sockfd,connfd;
    
    int tcp_listen(){
        struct sockaddr_in serv;
        int sockfd;
    
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        assert(sockfd);
        bzero(&serv,sizeof(serv));
        serv.sin_family=AF_INET;
        serv.sin_port=htons(SERV_PORT);
        serv.sin_addr.s_addr=inet_addr("127.0.0.1");
    
        assert(bind(sockfd,(struct sockaddr *)&serv,sizeof(serv)) == 0);
        assert(listen(sockfd,10) == 0);
        return sockfd;
    }
    
    void sig_urg(int signo){
        int n;
        char buff[10];
    
        printf("SIGURG received
    ");
        n=recv(connfd,buff,sizeof(buff)-1,MSG_OOB);
        buff[n]=0;
        printf("read %d OOB bytes: %s
    ",n,buff);
    }
    
    int main(int argc, char *argv[]) {
        sockfd=tcp_listen();
        connfd=accept(sockfd,NULL,NULL);
    
        signal(SIGURG,sig_urg);
        fcntl(connfd,F_SETOWN,getpid());
    
        int n;
        char buff[100];
        for(;;){
            if((n=read(connfd,buff,sizeof(buff)-1)) == 0){
                printf("received EOF
    ");
                exit(0);
            }
            buff[n]=0;
            printf("read %d bytes: %s
    ",n,buff);
        }
        return 0;
    }
    
  • 相关阅读:
    python 调用dll 动态链接库 结构体参数及回调函数等示例
    逆向x64-small-trick
    Malloc碎碎念
    关于OF和CF
    月赛-Crackhash
    ARM64调试环境
    Apache Kafka(六)- High Throughput Producer
    Apache Kafka(五)- Safe Kafka Producer
    Apache Kafka(四)- 使用 Java 访问 Kafka
    Apache Kafka(三)- Kakfa CLI 使用
  • 原文地址:https://www.cnblogs.com/cfans1993/p/6598327.html
Copyright © 2020-2023  润新知