MSG_OOB unixc

MSG_OOB : 僅僅是經過tcp頭的urgent 模式傳送的,socket

且只會讀取一個字節做爲oob數據

                 例如:send(sockfd,"1234",strlen("1234"),MSG_OOB);

                         只有最後一個字節:4 將被看成oob數據 ,其餘數據"123"將被看成普通數據讀取

須要注意:tcp

此類數據經過信號 SIGURG 來通知 ,因此須要使用 signal / sigaction 來註冊一個信號處理函數.函數

在signal 以前首先須要 fcntl(clientfd,F_SETOWN,getpid()) 操作系統

因爲此信號是由套接字產生的, 而套接字的擁有者是操做系統 . 只有把套接字的擁有者設置爲當前進程, SIGURG纔會被code

傳遞到此進程, 不然將接受不到SIGURG信號,只能接受普通數據.orm

MSG_PEEK : 偷窺一下緩衝區中有沒有數據, recv(clientfd,buf,BUFSIZ,MSG_PEEK) ,並不會從緩衝區移除數據.進程

MSG_DONTWAIT : 不阻塞ip

oob_recv.cget

#include "util.h"
#include <signal.h>
static void urg_handler(int sig);
int clientfd = 0;
int main(int argc, char ** argv)
{
    int listenfd = socket(AF_INET, SOCK_STREAM,0);
    struct sockaddr_in serv_addr,client_addr;
    memset(&serv_addr,0,sizeof(serv_addr));
    memset(&client_addr,0,sizeof(client_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = INADDR_ANY;
 
    if(bind(listenfd,(SA*)&serv_addr,sizeof(serv_addr)) < 0){
        perror("bind");
        return  0;
    }
    if(listen(listenfd,BACKLOG) < 0){
        perror("listen");
        return 0;
    }
 
    socklen_t  client_socklen =sizeof(client_addr);
    clientfd = accept(listenfd,(SA*)&client_addr,&client_socklen);
 
    //注意, 若是不設置套接字擁有者, 此進程將收不到SIGURG 信號.
    fcntl(clientfd,F_SETOWN,getpid());
    //註冊信號函數
    signal(SIGURG,urg_handler);
 
    int n = 0;
    char buf[BUFSIZ];
 
    
//    while(1){
//        printf("檢查數據是否存在\n");
//        n = recv(clientfd,buf,BUFSIZ,MSG_PEEK|MSG_DONTWAIT);
//        printf("數據長度 : %d ,errno:%d\n", n,errno);
//        if(n > 0){
//            puts("有數據了");
//            break;
//        }
//
//    }
 
    
    //接受普通數據.
    while((n = recv(clientfd,buf,BUFSIZ,0)) != 0){
        if( -1 == n){
            perror("recv error");
            printf("error no : %d\n" ,errno);
            continue;
        }
        buf[n] = 0;
        printf("normal buf:%s\n",buf);
    }
    close(clientfd);
    close(listenfd);
    return 0;
}
static void urg_handler(int sig)
{
    char buf[30];
 
    //接受OOB數據, 只能接受最後一個字節, 其餘字節做爲普通數據接受
    int n = recv(clientfd ,buf,30,MSG_OOB);
    printf("oob len : %d\n" , n);
    buf[n] = 0;
    printf("oob data:%s\n" , buf);
}

oob_send.cit

#include "util.h"
 
int main(int argc, char ** argv)
{
    if ( argc != 3){
        puts(" ip port");
        return 0;
    }
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in sin;
    memset(&sin,0,sizeof(sin));
    sin.sin_port = htons(atoi(argv[2]));
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    sin.sin_family = AF_INET;
 
    connect(sockfd,(SA*)&sin,sizeof(sin));
 
    char data[] = "data1" , data2[] = "data2";
    char oob_data1[] = "oobdata1" , oob_data2[] = "oob_data2";
 
    write(sockfd,data,strlen(data));
    
    //發送oob數據 , 只有最後一個字節將被看成oob數據
    send(sockfd,oob_data1,strlen(oob_data1),MSG_OOB);
    write(sockfd,data2,strlen(data2));
 
    //發送oob數據 , 只有最後一個字節將被看成oob數據 
    send(sockfd,oob_data2,strlen(oob_data2),MSG_OOB);
    close(sockfd);
    return 0;
}
本站公眾號
   歡迎關注本站公眾號,獲取更多信息