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;
    }
    
  • 相关阅读:
    FBX Software Development Kit
    如何用Nsight调试C# OpenGL程序
    Xcode如何编译Debug版和Release版
    Mapbox
    OpenGL
    OpenGL Tutorial
    Unity3D Sprite Draw Call合批规则
    MONO加载DLL调试命令
    如何在Flash Builder里新建ActionScript工程
    Flash Frameworks
  • 原文地址:https://www.cnblogs.com/cfans1993/p/6598327.html
Copyright © 2011-2022 走看看