2015-10-12 111 views
3

我正在尝试使用支持IPV4或IPV6的东西。 这两个代码是相似的,所以我尝试了这样的东西。 由于代码后面的唯一区别取决于这个sin变量,我怎么才能编译其中的一个。让我们在IF语句假设“IPV”变量是真还是假取决于用户输入声明变量名称相同但类型不同

//FOR IPV4 
//struct sockaddr_in sin; 
//FOR IPV6 
//struct sockaddr_in6 sin; 
//IPV4 


// IPV4 --------------------------------------- 
if (ipv){ 
    struct sockaddr_in sin; 
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 
    perror("Chyba pri vytvareni socketu"); 
    return -1; 
    } 


    sin.sin_family = AF_INET;  
    sin.sin_port = htons(port_number); 
    sin.sin_addr.s_addr = INADDR_ANY; 
} 

// IPV6 --------------------------------------- 
else{ 

    struct sockaddr_in6 sin; 
    if ((s = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { 
    perror("Chyba pri vytvareni socketu"); 
    return -1; 
    } 

    sin.sin6_family = AF_INET6;  
    sin.sin6_port = htons(port_number); 
    sin.sin6_addr = in6addr_any; 
    sin.sin6_flowinfo = 0; 
} 

if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 
    printf("error on bind\n"); return -1; 
} 

if (listen(s, 5)) { 
    printf ("error on listen\n"); 
return -1; 
} 

sinlen = sizeof(sin); 
pid_t pid; 

while (1) { 


    /* accepting new connection request from client, 
    socket id for the new connection is returned in t */ 
    if ((t = accept(s, (struct sockaddr *) &sin, &sinlen)) < 0) { 
     printf("error on accept\n"); /* accept error */ 
     return -1; 
    } 
continues .... not important 

这段代码给我:

server.cpp: In function ‘int main(int, char**)’: 
server.cpp:132:35: error: ‘sin’ was not declared in this scope 
    if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 
          ^
server.cpp:145:19: error: ‘sin’ was not declared in this scope 
    sinlen = sizeof(sin); 
      ^
make: *** [all] Error 1 

所以问题是,我怎样才能使这个工作,而无需编写相同用不同的“罪”代码两次;

+0

更改变量名称。名字'sin'与数学库中的sin(三角函数)函数冲突。 –

+0

在if之前使变量'sockaddr sin'变成'if',并用你的本地'sin'在每个'if'的enc中初始化它。 –

+1

@ThomasMatthews不,它不是。 –

回答

1

这是一个典型的案例,您可以使用工会

typedef union { 
    struct sockaddr_in v4; 
    struct sockaddr_in6 v6; 
} sockaddr_union; 

sockaddr_union sin; 

然后,当你知道你正在使用IPv4,到位罪的使用sin.v4,当你知道你正在使用IPV6工作,使用sin.v6

+1

不要称之为'sockaddr_un'。这是用于UNIX域套接字的结构体的名称。 – dbush

+0

哦真的很抱歉 –

2

我做到了像这样通过使用sockaddr_storage并且工作良好

struct sockaddr_storage sin; 
struct sockaddr_in *sin4; 
struct sockaddr_in *sin6; 
// IPV4 --------------------------------------- 
if (ipv == true){ 
    sin4 = (struct sockaddr_in*)&sin; 
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 
     perror("Chyba pri vytvareni socketu"); 
     return -1; 
    } 


    sin4->sin_family = AF_INET;  
    sin4->sin_port = htons(port_number); 
    sin4->sin_addr.s_addr = INADDR_ANY; 
} 

// IPV6 --------------------------------------- 
else{ 

    sin6 = (struct sockaddr_in6*)&sin; 
    if ((s = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { 
     perror("Chyba pri vytvareni socketu"); 
     return -1; 
    } 

    sin6->sin6_family = AF_INET6;  
    sin6->sin6_port = htons(port_number); 
    sin6->sin6_addr = in6addr_any; 
    sin6->sin6_flowinfo = 0; 
} 

if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 
    printf("error on bind\n"); return -1; 
} 

if (listen(s, 5)) { 
    printf ("error on listen\n"); 
    return -1; 
} 

sinlen = sizeof(sin); 
pid_t pid; 

while (1) { 


    /* accepting new connection request from client, 
    socket id for the new connection is returned in t */ 
    if ((t = accept(s, (struct sockaddr *) &sin, &sinlen)) < 0) { 
     printf("error on accept\n"); /* accept error */ 
    return -1; 
    } 
    continues .... not important 
相关问题