我正在尝试制作支持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 bindn"); return -1;
}
if (listen(s, 5)) {
printf ("error on listenn");
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 acceptn"); /* 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
那么问题是我如何做到这一点,而不写相同的代码两次不同的"sin";
我是这样做的,通过使用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 bindn"); return -1;
}
if (listen(s, 5)) {
printf ("error on listenn");
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 acceptn"); /* accept error */
return -1;
}
continues .... not important
这是使用联合的典型情况。
typedef union {
struct sockaddr_in v4;
struct sockaddr_in6 v6;
} sockaddr_union;
sockaddr_union sin;
然后,当您知道您正在使用IPV4时,使用sin。v4代替sin,当你知道你正在使用IPV6时,使用sin.v6