zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    网络摄像头监控中什么情况下需要使用流媒体转发服务器?
    流媒体播放器播放h264编码视频与h265编码视频哪个更清晰?
    RTMP推流视频流媒体服务如何实现网络传输?
    web视频直播服务器更改端口号后录像功能失效问题解决
    互联网视频直播/点播流媒体服务器使用http和rtmp做点播时有什么区别?
    视频互联网直播/点播服务器中关于内容分发CDN的相关问题汇总
    网页直播系统推流端和拉流端都有哪些环节?
    自建视频流媒体服务器需要满足哪些条件?
    线上课堂教育行业选择互动直播时有哪些直播方案?
    互联网直播点播平台在进行iframe直播分享时如何禁止本地视频自动播放?
  • 原文地址:https://www.cnblogs.com/cfans1993/p/6598327.html
Copyright © 2011-2022 走看看