ipv6网络通信方式

时间:2024-05-22 14:21:30

关于ipv6网络编程方式

1. 通常我们使用的都是ipv4的方式来进行网路编程通信,本次介绍的是ipv6方式通信方式。

直接根据代码实例来说明,以及使用中需要注意事项。

2在linux环境下,我们使用ifconfig命令查询网卡信息如下:

ipv6网络通信方式

 

如上图所示,inet6中两个ipv6地址,这连个地址是有区别的,就是尾部的Global和Link两个关键字。要想使用ipv6进行网路通信,不能使用Link标识的inet6字段,因为该地址私有地址,供给内核使用。所以需要我们使用手动添加相应的ipv6地址且标识为Globalinet6地址来进行通信。如果网卡没有该标识的inet6地址,可手动添加。命令如下:

顺带介绍下ifconfig命令的参数含义,如下图所示:

ipv6网络通信方式

例如:

ifconfig eth0 add 2001:da8:e000::1:1:1,

之后在使用ifconfig命令即可查看上图所示带有Global标识的inet6地址。好了,不多说,直接来看在tcp下使用inet6地址通信的代码实现方式。

3.Tcp通信代码使用举例

Tcp方式:

Server.cpp:

 

#include <iostream>

#include <stdio.h>

#include <unistd.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <errno.h>

#include <pthread.h>

using namespace std;

void* echo(void* argc){

while(1){

int confd = *(int*)argc;

char buff[1024] = {0};

int rec_len = recv(confd,buff,1024,0);

cout<<"recv info is "<<buff<<endl;

sleep(1);

}

}

int main(int argc,char** argv){

int sockfd,acpfd;

string ipv6 = "";

if(argc == 2){

ipv6.assign(argv[1]);

}else{

return -1;

}

int ipv6_port = 9000;

struct sockaddr_in6 sockaddr_ipv6,cli_ipv6;

sockfd = socket(AF_INET6,SOCK_STREAM,0);

if(sockfd == -1){

return -1;

}

sockaddr_ipv6.sin6_family = AF_INET6;

sockaddr_ipv6.sin6_port = htons(ipv6_port);

if(argc == 2){

inet_pton(AF_INET6,ipv6.c_str(),&sockaddr_ipv6.sin6_addr);

}else{

sockaddr_ipv6.sin6_addr = in6addr_any;

}

 

//ipv6结构体

// struct sockaddr_in6 {

//  __uint8_t sin6_len;    /* length of this struct(sa_family_t) */

//  sa_family_t sin6_family;/* AF_INET6 (sa_family_t) */

//  in_port_t sin6_port;    /* Transport layer port # (in_port_t) */

// __uint32_t sin6_flowinfo;/* IP6 flow information */

// struct in6_addr sin6_addr;/* IP6 address */

//  __uint32_t sin6_scope_id;/* scope zone index */

// };

if(bind(sockfd,(struct sockaddr*)&sockaddr_ipv6,sizeof(sockaddr_ipv6)) == -1){

return -1;

}

 

if(listen(sockfd,1024) == -1){

return -1;

}

 

while(1){

socklen_t len = sizeof(cli_ipv6);

acpfd = accept(sockfd,(struct sockaddr*)&cli_ipv6,&len);

cout<<"accept a connect"<<acpfd<<endl;

if(acpfd == -1){

continue;

}

pthread_t id;

if(0 != pthread_create(&id,NULL,echo,(void*)&acpfd)){

continue;

}

sleep(1);

}

close(acpfd);

close(sockfd);

return 0;

}

 

Client.cpp

 

#include <iostream>

#include <stdio.h>

#include <unistd.h>

#include <sys/time.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#include <errno.h>

#include <pthread.h>

using namespace std;

int main(int argc,char** argv){

int sockfd,acpfd;

string ipv6 = "";

ipv6.assign(argv[1]);

int ipv6_port = 9000;

struct sockaddr_in6 sockaddr_ipv6;

sockfd = socket(AF_INET6,SOCK_STREAM,0);

if(sockfd == -1){

cout<<"socker is failed"<<endl;

return -1;

}

sockaddr_ipv6.sin6_family = AF_INET6;

sockaddr_ipv6.sin6_port = htons(ipv6_port);

inet_pton(AF_INET6,ipv6.c_str(), &sockaddr_ipv6.sin6_addr);

 

// struct sockaddr_in6 {

//  __uint8_t sin6_len;    /* length of this struct(sa_family_t) */

//  sa_family_t sin6_family;/* AF_INET6 (sa_family_t) */

//  in_port_t sin6_port;    /* Transport layer port # (in_port_t) */

// __uint32_t sin6_flowinfo;/* IP6 flow information */

// struct in6_addr sin6_addr;/* IP6 address */

//  __uint32_t sin6_scope_id;/* scope zone index */

// };

if(connect(sockfd,(struct sockaddr*)&sockaddr_ipv6,sizeof(sockaddr_ipv6)) == -1){

perror("connect:");

return -1;

}

char buff[]={"Welcome to python world !"};

while(1){

cout<<"will send data is "<<buff<<endl;

int snd_len = send(sockfd,buff,sizeof(buff),0);

if(snd_len <= 0){

continue;

}

sleep(1);

}

close(sockfd);

return 0;

}

编译代码:

g++ -g tcp_ser_ipv6.cpp -o tcp_ser_ipv6 -lpthread

g++ -g tcp_cli_ipv6.cpp -o tcp_cli_ipv6 -lpthread

结果如下:

 ipv6网络通信方式

ipv6网络通信方式

 

注:(如果在同一网段中的不同机器上进行通信连接,需注意防火墙是否关闭,针对inet6地址的防火墙它有自己的防火墙名为ip6tables,关闭即可,负责客户端进行连接是会出现connect:: Permission denied错误,或者在ip6tables防火墙配置中配置对应的端口放行即可,在udt封装的协议中,如果防火墙未关闭,会出现Connection setup failure: connection time out.将在后面介绍udt的使用方式,具体配置可参考博主中的socket连接标题的短文介绍过程)。

查看防火墙状态:service ip6tables status   

关闭防火墙:service ip6tables stop