UNIX(网络编程-基本用法):07---案例(检查套接字选项是否受支持并获取默认值)

一、程序

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/sctp.h>
union val{
    int i_val;
    long l_val;
    struct linger linger_val;
    struct timeval timeval_val;
}val;

static char strres[128];
static char *sock_str_flag(union val* ptr,int len)
{
    if(len !=sizeof(int)){
        snprintf(strres,sizeof(strres),"size (%d) not sizeof(int)",len);
    }
    else{
        snprintf(strres,sizeof(strres),"%s",(ptr->i_val==0)?"off":"on");
    }
    return(strres);
}

static char strres[128];
static char *sock_str_int(union val* ptr,int len)
{
    if(len !=sizeof(int)){
        snprintf(strres,sizeof(strres),"size (%d) not sizeof(int)",len);
    }
    else{
        snprintf(strres,sizeof(strres),"%s",(ptr->i_val==0)?"off":"on");
    }
    return(strres);
}

static char strres[128];
static char *sock_str_linger(union val* ptr,int len)
{
    if(len !=sizeof(int)){
        snprintf(strres,sizeof(strres),"size (%d) not sizeof(int)",len);
    }
    else{
        snprintf(strres,sizeof(strres),"%s",(ptr->i_val==0)?"off":"on");
    }
    return(strres);
}

static char strres[128];
static char *sock_str_timeval(union val* ptr,int len)
{
    if(len !=sizeof(int)){
        snprintf(strres,sizeof(strres),"size (%d) not sizeof(int)",len);
    }
    else{
        snprintf(strres,sizeof(strres),"%s",(ptr->i_val==0)?"off":"on");
    }
    return(strres);
}

struct sock_opts{
    const char *opt_str;
    int opt_level;
    int opt_name;
    char *(*opt_val_str)(union val *,int);
}sock_opts[]={
    {"SO_BROADCAST",SOL_SOCKET,SO_BROADCAST,sock_str_flag},
    {"SO_DEBUG",SOL_SOCKET,SO_DEBUG,sock_str_flag},
    {"SO_DONTROUTE",SOL_SOCKET,SO_DONTROUTE,sock_str_flag},
    {"SO_ERROR",SOL_SOCKET,SO_ERROR,sock_str_int},
    {"SO_KEEPALIVE",SOL_SOCKET,SO_KEEPALIVE,sock_str_flag},
    {"SO_LINGER",SOL_SOCKET,SO_LINGER,sock_str_linger},
    {"SO_OOBINLINE",SOL_SOCKET,SO_OOBINLINE,sock_str_flag},
    {"SO_RCVBUF",SOL_SOCKET,SO_RCVBUF,sock_str_int},
    {"SO_SNDBUF",SOL_SOCKET,SO_SNDBUF,sock_str_int},
    {"SO_RCVLOWAT",SOL_SOCKET,SO_RCVLOWAT,sock_str_int},
    {"SO_SNDLOWAT",SOL_SOCKET,SO_SNDLOWAT,sock_str_int},
    {"SO_RCVTIMEO",SOL_SOCKET,SO_RCVTIMEO,sock_str_timeval},
    {"SO_SNDTIMEO",SOL_SOCKET,SO_SNDTIMEO,sock_str_timeval},
    {"SO_REUSEADDR",SOL_SOCKET,SO_REUSEADDR,sock_str_flag},
#ifdef SO_REUSERORT
    {"SO_REUSERORT",SOL_SOCKET,SO_REUSEPORT,sock_str_flag},
#else
    {"SO_REUSERORT",0,0,NULL},
#endif
    {"SO_TYPE",SOL_SOCKET,SO_TYPE,sock_str_int},
    //{"SO_USELOOPBACK",SOL_SOCKET,SO_USELOOPBACK,sock_str_flag},
    {"IP_TOS",IPPROTO_IP,IP_TOS,sock_str_int},
    {"IP_TTL",IPPROTO_IP,IP_TTL,sock_str_int},
    //{"IPV6_DONTFRAG",IPPROTO_IP6,IPV6_DONTFRAG,sock_str_flag},
    {"IPV6_UNICAST_HOPS",IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int},
    {"IPV6_V6ONLY",IPPROTO_IPV6,IPV6_V6ONLY,sock_str_flag},
    //{"TCP_MAXSEG",IPPROTO_TCP,TCP_MAXSEG,sock_str_int},
    //{"TCP_NODELAY",IPPROTO_TCP,TCP_NODELAY,sock_str_flag},
    {"SCTP_AUTOCLOSE",IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int},
    //{"SCTP_MAXBURST",IPPROTO_SCTP,SCTP_MAXBURST,sock_str_int},
    {"SCTP_MAXSEG",IPPROTO_SCTP,SCTP_MAXSEG,sock_str_int},
    {"SCTP_NODELAY",IPPROTO_SCTP,SCTP_NODELAY,sock_str_flag},
    {NULL,0,0,NULL},                                            
};


int main(int argc,char *argv[])
{
    int fd;
    socklen_t len;
    struct sock_opts *ptr;
    for(ptr=sock_opts;ptr->opt_str!=NULL;ptr++){
        printf("%s:",ptr->opt_str);
        if(ptr->opt_val_str==NULL)
            printf("(undefined)\n");
        else{
            switch(ptr->opt_level){
                case SOL_SOCKET:
                case IPPROTO_IP:
                case IPPROTO_TCP:
                    fd=socket(AF_INET,SOCK_STREAM,0);
                    break;
                default:
                    printf("Can't create fd for level %d\n",ptr->opt_level);
            }
            len=sizeof(val);
            if(getsockopt(fd,ptr->opt_level,ptr->opt_name,&val,&len)==-1)
                perror("getsockopt error");
            else
                printf("default = %s\n",(*ptr->opt_val_str)(&val,len));
            close(fd);
        }
    }
    exit(0);
}

程序解释

  • 因为getsockopt参数4只有4中数据类型,我们用union表示

程序还有一些没有细节没有实现

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/89536013