2015-10-12 144 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 
相關問題