一、TCP socket ipv6与ipv4的区别

服务器端源代码如下:

[cpp] view plain copy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #include <arpa/inet.h>
  11. #define MAXBUF 1024
  12. int main(int argc, char **argv)
  13. {
  14. int sockfd, new_fd;
  15. socklen_t len;
  16. /* struct sockaddr_in my_addr, their_addr; */ // IPv4
  17. struct sockaddr_in6 my_addr, their_addr; // IPv6
  18. unsigned int myport, lisnum;
  19. char buf[MAXBUF + 1];
  20. if (argv[1])
  21. myport = atoi(argv[1]);
  22. else
  23. myport = 7838;
  24. if (argv[2])
  25. lisnum = atoi(argv[2]);
  26. else
  27. lisnum = 2;
  28. /* if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { */ // IPv4
  29. if ((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { // IPv6
  30. perror("socket");
  31. exit(1);
  32. } else
  33. printf("socket created/n");
  34. bzero(&my_addr, sizeof(my_addr));
  35. /* my_addr.sin_family = PF_INET; */ // IPv4
  36. my_addr.sin6_family = PF_INET6;    // IPv6
  37. /* my_addr.sin_port = htons(myport); */ // IPv4
  38. my_addr.sin6_port = htons(myport);   // IPv6
  39. if (argv[3])
  40. /* my_addr.sin_addr.s_addr = inet_addr(argv[3]); */ // IPv4
  41. inet_pton(AF_INET6, argv[3], &my_addr.sin6_addr);  // IPv6
  42. else
  43. /* my_addr.sin_addr.s_addr = INADDR_ANY; */ // IPv4
  44. my_addr.sin6_addr = in6addr_any;            // IPv6
  45. /* if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) */ // IPv4
  46. if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6))  // IPv6
  47. == -1) {
  48. perror("bind");
  49. exit(1);
  50. } else
  51. printf("binded/n");
  52. if (listen(sockfd, lisnum) == -1) {
  53. perror("listen");
  54. exit(1);
  55. } else
  56. printf("begin listen/n");
  57. while (1) {
  58. len = sizeof(struct sockaddr);
  59. if ((new_fd =
  60. accept(sockfd, (struct sockaddr *) &their_addr,
  61. &len)) == -1) {
  62. perror("accept");
  63. exit(errno);
  64. } else
  65. printf("server: got connection from %s, port %d, socket %d/n",
  66. /* inet_ntoa(their_addr.sin_addr), */ // IPv4
  67. inet_ntop(AF_INET6, &their_addr.sin6_addr, buf, sizeof(buf)), // IPv6
  68. /* ntohs(their_addr.sin_port), new_fd); */ // IPv4
  69. their_addr.sin6_port, new_fd); // IPv6
  70. /* 开始处理每个新连接上的数据收发 */
  71. bzero(buf, MAXBUF + 1);
  72. strcpy(buf,
  73. "这是在连接建立成功后向客户端发送的第一个消息/n只能向new_fd这个用accept函数新建立的socket发消息,不能向sockfd这个监听socket发送消息,监听socket不能用来接收或发送消息/n");
  74. /* 发消息给客户端 */
  75. len = send(new_fd, buf, strlen(buf), 0);
  76. if (len < 0) {
  77. printf
  78. ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'/n",
  79. buf, errno, strerror(errno));
  80. } else
  81. printf("消息'%s'发送成功,共发送了%d个字节!/n",
  82. buf, len);
  83. bzero(buf, MAXBUF + 1);
  84. /* 接收客户端的消息 */
  85. len = recv(new_fd, buf, MAXBUF, 0);
  86. if (len > 0)
  87. printf("接收消息成功:'%s',共%d个字节的数据/n",
  88. buf, len);
  89. else
  90. printf
  91. ("消息接收失败!错误代码是%d,错误信息是'%s'/n",
  92. errno, strerror(errno));
  93. /* 处理每个新连接上的数据收发结束 */
  94. }
  95. close(sockfd);
  96. return 0;
  97. }

每行程序后面的 “//IPv4” 表示这行代码是在IPv4网络里用的
而“//IPv6” 表示这行代码是在IPv6网络里用的,比较一下,会很容易看到差别的。
客户端源代码如下:

[cpp] view plain copy
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <sys/socket.h>
  5. #include <resolv.h>
  6. #include <stdlib.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>
  10. #define MAXBUF 1024
  11. int main(int argc, char **argv)
  12. {
  13. int sockfd, len;
  14. /* struct sockaddr_in dest; */ // IPv4
  15. struct sockaddr_in6 dest;      // IPv6
  16. char buffer[MAXBUF + 1];
  17. if (argc != 3) {
  18. printf
  19. ("参数格式错误!正确用法如下:/n/t/t%s IP地址 端口/n/t比如:/t%s 127.0.0.1 80/n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
  20. argv[0], argv[0]);
  21. exit(0);
  22. }
  23. /* 创建一个 socket 用于 tcp 通信 */
  24. /* if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { */ // IPv4
  25. if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {      // IPv6
  26. perror("Socket");
  27. exit(errno);
  28. }
  29. printf("socket created/n");
  30. /* 初始化服务器端(对方)的地址和端口信息 */
  31. bzero(&dest, sizeof(dest));
  32. /* dest.sin_family = AF_INET; */  // IPv4
  33. dest.sin6_family = AF_INET6;     // IPv6
  34. /* dest.sin_port = htons(atoi(argv[2])); */ // IPv4
  35. dest.sin6_port = htons(atoi(argv[2]));     // IPv6
  36. /* if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { */ // IPv4
  37. if ( inet_pton(AF_INET6, argv[1], &dest.sin6_addr) < 0 ) {                 // IPv6
  38. perror(argv[1]);
  39. exit(errno);
  40. }
  41. printf("address created/n");
  42. /* 连接服务器 */
  43. if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
  44. perror("Connect ");
  45. exit(errno);
  46. }
  47. printf("server connected/n");
  48. /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
  49. bzero(buffer, MAXBUF + 1);
  50. /* 接收服务器来的消息 */
  51. len = recv(sockfd, buffer, MAXBUF, 0);
  52. if (len > 0)
  53. printf("接收消息成功:'%s',共%d个字节的数据/n",
  54. buffer, len);
  55. else
  56. printf
  57. ("消息接收失败!错误代码是%d,错误信息是'%s'/n",
  58. errno, strerror(errno));
  59. bzero(buffer, MAXBUF + 1);
  60. strcpy(buffer, "这是客户端发给服务器端的消息/n");
  61. /* 发消息给服务器 */
  62. len = send(sockfd, buffer, strlen(buffer), 0);
  63. if (len < 0)
  64. printf
  65. ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'/n",
  66. buffer, errno, strerror(errno));
  67. else
  68. printf("消息'%s'发送成功,共发送了%d个字节!/n",
  69. buffer, len);
  70. /* 关闭连接 */
  71. close(sockfd);
  72. return 0;
  73. }

编译程序用下列命令:
gcc -Wall ipv6-server.c -o ipv6server
gcc -Wall ipv6-client.c -o ipv6client
你自己的主机有IPv6地址吗?很多人会问,输入ifconfig命令看一下吧:

eth0      链路封装:以太网  硬件地址 00:14:2A:6D:5B:A5  
          inet 地址:192.168.0.167  广播:192.168.0.255  掩码:255.255.255.0
          inet6 地址: fe80::214:2aff:fe6d:5ba5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  跃点数:1
          接收数据包:30507 错误:0 丢弃:0 过载:0 帧数:0
          发送数据包:26797 错误:0 丢弃:0 过载:0 载波:0
          碰撞:0 发送队列长度:1000 
          接收字节:31461154 (30.0 MiB)  发送字节:4472810 (4.2 MiB)
          中断:185 基本地址:0xe400

lo        链路封装:本地环回  
          inet 地址:127.0.0.1  掩码:255.0.0.0
          inet6 地址: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  跃点数:1
          接收数据包:13 错误:0 丢弃:0 过载:0 帧数:0
          发送数据包:13 错误:0 丢弃:0 过载:0 载波:0
          碰撞:0 发送队列长度:0 
          接收字节:1178 (1.1 KiB)  发送字节:1178 (1.1 KiB)

看到“inet6 地址:”这两行了吗?后面就是你的IPv6地址

启动服务:
./ipv6server 7838 1
或者加上IP地址启动服务:
./ipv6server 7838 1 fe80::214:2aff:fe6d:5ba5

启动客户端测试一下:
./ipv6client ::1/128 7838 

./ipv6client fe80::214:2aff:fe6d:5ba5 7838

二、UDP ipv6例子

UDP服务端:

[cpp] view plain copy
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <arpa/inet.h>
  4. #include <sys/socket.h>
  5. #include <string.h>
  6. #define LOCALPORT 8888
  7. int main(int argc,char *argv[])
  8. {
  9. int mysocket,len;
  10. int i=0;
  11. struct sockaddr_in6 addr;
  12. int addr_len;
  13. char msg[200];
  14. char buf[300];
  15. if((mysocket=socket(AF_INET6,SOCK_DGRAM,0))<0)
  16. {
  17. perror("error:");
  18. return(1);
  19. }
  20. else
  21. {
  22. printf("socket created ...\n");
  23. printf("socket id :%d \n",mysocket);
  24. }
  25. addr_len=sizeof(struct sockaddr_in6);
  26. bzero(&addr,sizeof(addr));
  27. addr.sin6_family=AF_INET6;
  28. addr.sin6_port=htons(LOCALPORT);
  29. addr.sin6_addr=in6addr_any;
  30. if(bind(mysocket,(struct sockaddr *)&addr,sizeof(addr))<0)
  31. {
  32. perror("connect");
  33. return(1);
  34. }
  35. else
  36. {
  37. printf("bink ok .\n");
  38. printf("local port : %d\n",LOCALPORT);
  39. }
  40. while(1)
  41. {
  42. bzero(msg,sizeof(msg));
  43. len = recvfrom(mysocket,msg,sizeof(msg),0,(struct sockaddr *)&addr,(socklen_t*)&addr_len);
  44. printf("%d:",i);
  45. i++;
  46. inet_ntop(AF_INET6,&addr.sin6_addr,buf,sizeof(buf));
  47. printf("message from ip %s",buf);
  48. printf("Received message : %s\n",msg);
  49. if(sendto(mysocket,msg,len,0,(struct sockaddr *)&addr,addr_len)<0)
  50. {
  51. printf("error");
  52. return(1);
  53. }
  54. }
  55. }

UDP客户端代码:

[cpp] view plain copy
  1. #include <stdio.h>
  2. #include <arpa/inet.h>
  3. #include <unistd.h>
  4. #include <sys/socket.h>
  5. #include <string.h>
  6. #define REMOTEPORT 8888
  7. #define REMOTEIP "::1"
  8. int main(int argc,char *argv[])
  9. {
  10. int mysocket,len;
  11. int i=0;
  12. struct sockaddr_in6 addr;
  13. int addr_len;
  14. char msg[200];
  15. if((mysocket=socket(AF_INET6,SOCK_DGRAM,0))<0)
  16. {
  17. perror("error:");
  18. return(1);
  19. }
  20. else
  21. {
  22. printf("socket created ...\n");
  23. printf("socket id :%d \n",mysocket);
  24. printf("rmote ip : %s\n",REMOTEIP);
  25. printf("remote port :%d \n",REMOTEPORT);
  26. }
  27. addr_len=sizeof(struct sockaddr_in6);
  28. bzero(&addr,sizeof(addr));
  29. addr.sin6_family=AF_INET6;
  30. addr.sin6_port=htons(REMOTEPORT);
  31. inet_pton(AF_INET6,REMOTEIP,&addr.sin6_addr);
  32. while(1)
  33. {
  34. bzero(msg,sizeof(msg));
  35. len=read(STDIN_FILENO,msg,sizeof(msg));
  36. if(sendto(mysocket,msg,sizeof(msg),0,(struct sockaddr *)&addr,addr_len)<0)
  37. {
  38. printf("error");
  39. return(1);
  40. }
  41. len=recvfrom(mysocket,msg,sizeof(msg),0,(struct sockaddr *)&addr,(socklen_t*)&addr_len);
  42. printf("%d:",i);
  43. i++;
  44. printf("Received message : %s\n",msg);
  45. }
  46. }

"::1"相当于ipv4下的lo,即127网段

三、ipv6环境下inet_pton和inet_ntop

附上一段ipv6环境下inet_pton和inet_ntop函数代码

[cpp] view plain copy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <arpa/inet.h>
  5. int main(int argc, char **argv)
  6. {
  7. unsigned char buf[sizeof(struct in6_addr)];
  8. int domain, s;
  9. char str[INET6_ADDRSTRLEN];
  10. if(argc != 3){
  11. fprintf(stderr, "usage: %s {i4|i6|<num>} string\n", argv[0]);
  12. exit(EXIT_FAILURE);
  13. }
  14. domain = (strcmp(argv[1], "i4") == 0) ? AF_INET:(strcmp(argv[1], "i6") == 0) ? AF_INET6 : atoi(argv[1]);
  15. //IP字符串 ——》网络字节流
  16. s = inet_pton(domain, argv[2], buf);
  17. if(s<=0)
  18. {
  19. if(0 == s)
  20. fprintf(stderr, "Not in presentation format\n");
  21. else
  22. perror("inet_pton");
  23. exit(EXIT_FAILURE);
  24. }
  25. //网络字节流 ——》IP字符串
  26. if(inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL){
  27. perror("inet ntop\n");
  28. exit(EXIT_FAILURE);
  29. }
  30. printf("%s\n", str);
  31. exit(EXIT_SUCCESS);
  32. }

四、兼容IPV4和IPV6地址代码

为了能够兼容ipv4和ipv6,可以组织代码如下:

[cpp] view plain copy
  1. #define ADDRESS_BUFFER 50
  2. typedef class address
  3. {
  4. private:
  5. short int sin_family; //address family AF_INET or AF_INET6
  6. union
  7. {
  8. char binary_addr4[IPV4_LEN];
  9. char binary_addr6[IPV6_LEN];
  10. }addr;
  11. char readable_addr[ADDRESS_BUFFER];
  12. public:
  13. address();
  14. bool operator == (const address &dst) const;
  15. bool operator != (const address &dst) const { return (*this == dst? false : true );}
  16. bool operator < (const address &dst) const;
  17. const char* get_readable_address() const {return readable_addr;}
  18. int get_family() const {return sin_family;}
  19. bool is_ipv6() const {return sin_family == AF_INET6;}
  20. void set_family(int af) {if(af != AF_INET && af != AF_INET6) return; sin_family = af;}
  21. bool set_from_readable_address(const char* readable_address);
  22. const char* get_binary_data() {return (char*)&addr;}
  23. }address;

这里最重要的函数是set_from_readable_address函数,该函数是整个类的入口,执行该函数需要传入一个可读的IP地址,ipv4应该是"xxx.xxx.xxx.xxx"形式,ipv6应该是如:“ff01::1”或者"ffec:afaf::111"等可读的格式,返回false代表转换格式遇到错误,下面贴上该函数的实现代码,其它函数有兴趣的可以自己实现

[cpp] view plain copy
  1. bool address::set_from_readable_address(const char* readable_address)
  2. {
  3. if(readable_address == NULL)
  4. return false;
  5. memset(addr.binary_addr6, 0, sizeof(addr.binary_addr6));
  6. const char*p = readable_address;
  7. int cnt = 0;
  8. for(; *p != '\0';p++)
  9. if(*p == ':')
  10. cnt++;
  11. if(cnt >= 2)
  12. {
  13. sin_family = AF_INET6;
  14. if( inet_pton(PF_INET6,readable_address,addr.binary_addr6) <= 0)
  15. return false;
  16. strncpy(readable_addr, readable_address, ADDRESS_BUFFER);
  17. }else
  18. {
  19. sin_family = AF_INET;
  20. if( inet_pton(PF_INET,readable_address,addr.binary_addr4) <= 0)
  21. return false;
  22. strncpy(readable_addr, readable_address, ADDRESS_BUFFER);
  23. }
  24. return true;
  25. }

【http://blog.csdn.net/hepeng597/article/details/7803277】

IPv6下网络编程实例相关推荐

  1. Linux下网络编程

    Linux下网络编程初步 Linux以其源代码公开闻名于世,并以其稳定性和可靠性雄霸操作系统领域,在网络应用技术方面使用得更加广泛.很久以来它就是Windows的重要对手之一.随着网络时代的来临,Li ...

  2. qt android 网络编程实例,QT网络编程Tcp下C/S架构的即时通信实例

    先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include #include #include # ...

  3. Linux网络编程实例分析

    最近由于工作原因需要温习一下Linux网络编程的部分基础知识,因此对之前写的Socket网络通信的代码进行了进一步优化和拓展,在不关闭一次Socket连接的基础上,对服务端加入循环读写的功能,同时加入 ...

  4. python网络编程实例简析

    本文实例讲述了python网络编程,分享给大家供大家参考. 具体方法如下: 服务端代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from SocketS ...

  5. linux下网络编程设置非阻塞,UNIX网络编程 非阻塞connect的实现

    一.<UNIX网络编程>-非阻塞connect 在一个TCP套接口被设置为非阻塞之后调用connect,connect会立即返回EINPROGRESS错误,表示连接操作正在进行中,但是仍未 ...

  6. python网络编程案例_python网络编程实例简析

    本文实例讲述了python网络编程,分享给大家供大家参考. 具体方法如下: 服务端代码如下: from SocketServer import(TCPServer as TCP, StreamRequ ...

  7. python编程例子-python网络编程实例简析

    本文实例讲述了python网络编程,分享给大家供大家参考. 具体方法如下: 服务端代码如下: from SocketServer import(TCPServer as TCP, StreamRequ ...

  8. Java学习之网络编程实例

    转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 多谢分享 网络编程 网络编程对于很多的初学者来说,都是很向往的一 ...

  9. Linux环境下网络编程杂谈

    今天我们说说"Pre-网络编程".内容比较杂,但都是在做网络应用程序开发过程中经常要遇到的问题. 一.大端.小端和网络字节序 小端字节序:little-endian,将低字节存放在 ...

最新文章

  1. **Git本地仓库图解
  2. 初始化CISCO路由器和交换机密码
  3. c++怎么输入带有空格的字符串_CCF CSP-J/S中常用的输入输出 总结(三)
  4. Java集合源码学习(四)HashMap
  5. OC中使用 static 、 extern、 const使用
  6. 前端学习(3271):js中this的使用
  7. Linux如何查询目录默认权限,如何设置UNIX/Linux中新创建目录或文件的默认权限
  8. Oracle11g常用数据字典(转)
  9. Linux Tomcat9 控制界面及管理配置
  10. 地表反照率数据、地表净辐射通量、太阳辐射数据、地表温度、地表显热通量、NDVI、NPP、土地利用数据
  11. 用linux给诺基亚手机刷机,凤凰刷机怎么给诺基亚手机刷机 凤凰给诺基亚手机刷机教程...
  12. iOS手势识别的工作原理
  13. 数据库表及字段命名规范
  14. 分支定界-附Python代码
  15. 如何通过stm32驱动电源检测芯片cs5463
  16. STM32F103时钟系统
  17. 回望2019,互联网产品发展只剩焦虑?
  18. Dell EMC VxRail超融合节点升级混合云软件
  19. MySQL简介、M有SQL的存储引擎、表、字段和数据
  20. promise的实例方法、静态方法

热门文章

  1. 从零开始学Node.js(二)
  2. C++——override
  3. Redis 写磁盘出错 Cannot allocate memory
  4. 【深度学习系列】用PaddlePaddle和Tensorflow实现GoogLeNet InceptionV2/V3/V4
  5. select,poll,epoll区别
  6. 【翻译】Sencha Cmd中脚本压缩方法之比较
  7. aria-label及aria-labelledby应用//////////[信息无障碍产品联盟]
  8. Android之开启内置闹钟与已安装的应用程序设置
  9. qt翻译--QDragMoveEvent拖放类
  10. 一个失败的创意:GPGPU纹理化通用加速kD树的实现