TCP socket ipv6与ipv4的区别

一、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.   
  17.     /* struct sockaddr_in my_addr, their_addr; */ // IPv4  
  18.     struct sockaddr_in6 my_addr, their_addr; // IPv6  
  19.   
  20.     unsigned int myport, lisnum;  
  21.     char buf[MAXBUF + 1];  
  22.   
  23.     if (argv[1])  
  24.         myport = atoi(argv[1]);  
  25.     else  
  26.         myport = 7838;  
  27.   
  28.     if (argv[2])  
  29.         lisnum = atoi(argv[2]);  
  30.     else  
  31.         lisnum = 2;  
  32.   
  33.     /* if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { */ // IPv4  
  34.     if ((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1) { // IPv6  
  35.         perror("socket");  
  36.         exit(1);  
  37.     } else  
  38.         printf("socket created/n");  
  39.   
  40.     bzero(&my_addr, sizeof(my_addr));  
  41.     /* my_addr.sin_family = PF_INET; */ // IPv4  
  42.     my_addr.sin6_family = PF_INET6;    // IPv6  
  43.     /* my_addr.sin_port = htons(myport); */ // IPv4  
  44.     my_addr.sin6_port = htons(myport);   // IPv6  
  45.     if (argv[3])  
  46.         /* my_addr.sin_addr.s_addr = inet_addr(argv[3]); */ // IPv4  
  47.         inet_pton(AF_INET6, argv[3], &my_addr.sin6_addr);  // IPv6  
  48.     else  
  49.         /* my_addr.sin_addr.s_addr = INADDR_ANY; */ // IPv4  
  50.         my_addr.sin6_addr = in6addr_any;            // IPv6  
  51.   
  52.     /* if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) */ // IPv4  
  53.     if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6))  // IPv6  
  54.         == -1) {  
  55.         perror("bind");  
  56.         exit(1);  
  57.     } else  
  58.         printf("binded/n");  
  59.   
  60.     if (listen(sockfd, lisnum) == -1) {  
  61.         perror("listen");  
  62.         exit(1);  
  63.     } else  
  64.         printf("begin listen/n");  
  65.   
  66.     while (1) {  
  67.         len = sizeof(struct sockaddr);  
  68.         if ((new_fd =  
  69.              accept(sockfd, (struct sockaddr *) &their_addr,  
  70.                     &len)) == -1) {  
  71.             perror("accept");  
  72.             exit(errno);  
  73.         } else  
  74.             printf("server: got connection from %s, port %d, socket %d/n",  
  75.                    /* inet_ntoa(their_addr.sin_addr), */ // IPv4  
  76.                    inet_ntop(AF_INET6, &their_addr.sin6_addr, buf, sizeof(buf)), // IPv6  
  77.                    /* ntohs(their_addr.sin_port), new_fd); */ // IPv4  
  78.                    their_addr.sin6_port, new_fd); // IPv6  
  79.   
  80.         /* 开始处理每个新连接上的数据收发 */  
  81.         bzero(buf, MAXBUF + 1);  
  82.         strcpy(buf,  
  83.                "这是在连接建立成功后向客户端发送的第一个消息/n只能向new_fd这个用accept函数新建立的socket发消息,不能向sockfd这个监听socket发送消息,监听socket不能用来接收或发送消息/n");  
  84.         /* 发消息给客户端 */  
  85.         len = send(new_fd, buf, strlen(buf), 0);  
  86.         if (len < 0) {  
  87.             printf  
  88.                 ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'/n",  
  89.                  buf, errno, strerror(errno));  
  90.         } else  
  91.             printf("消息'%s'发送成功,共发送了%d个字节!/n",  
  92.                    buf, len);  
  93.   
  94.         bzero(buf, MAXBUF + 1);  
  95.         /* 接收客户端的消息 */  
  96.         len = recv(new_fd, buf, MAXBUF, 0);  
  97.         if (len > 0)  
  98.             printf("接收消息成功:'%s',共%d个字节的数据/n",  
  99.                    buf, len);  
  100.         else  
  101.             printf  
  102.                 ("消息接收失败!错误代码是%d,错误信息是'%s'/n",  
  103.                  errno, strerror(errno));  
  104.         /* 处理每个新连接上的数据收发结束 */  
  105.     }  
  106.   
  107.     close(sockfd);  
  108.     return 0;  
  109. }  
每行程序后面的 “//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.   
  18.     if (argc != 3) {  
  19.         printf  
  20.             ("参数格式错误!正确用法如下:/n/t/t%s IP地址 端口/n/t比如:/t%s 127.0.0.1 80/n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",  
  21.              argv[0], argv[0]);  
  22.         exit(0);  
  23.     }  
  24.     /* 创建一个 socket 用于 tcp 通信 */  
  25.     /* if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { */ // IPv4  
  26.     if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {      // IPv6  
  27.         perror("Socket");  
  28.         exit(errno);  
  29.     }  
  30.     printf("socket created/n");  
  31.   
  32.     /* 初始化服务器端(对方)的地址和端口信息 */  
  33.     bzero(&dest, sizeof(dest));  
  34.     /* dest.sin_family = AF_INET; */  // IPv4  
  35.     dest.sin6_family = AF_INET6;     // IPv6  
  36.     /* dest.sin_port = htons(atoi(argv[2])); */ // IPv4  
  37.     dest.sin6_port = htons(atoi(argv[2]));     // IPv6  
  38.     /* if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { */ // IPv4  
  39.     if ( inet_pton(AF_INET6, argv[1], &dest.sin6_addr) < 0 ) {                 // IPv6  
  40.         perror(argv[1]);  
  41.         exit(errno);  
  42.     }  
  43.     printf("address created/n");  
  44.   
  45.     /* 连接服务器 */  
  46.     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {  
  47.         perror("Connect ");  
  48.         exit(errno);  
  49.     }  
  50.     printf("server connected/n");  
  51.   
  52.     /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */  
  53.     bzero(buffer, MAXBUF + 1);  
  54.     /* 接收服务器来的消息 */  
  55.     len = recv(sockfd, buffer, MAXBUF, 0);  
  56.     if (len > 0)  
  57.         printf("接收消息成功:'%s',共%d个字节的数据/n",  
  58.                buffer, len);  
  59.     else  
  60.         printf  
  61.             ("消息接收失败!错误代码是%d,错误信息是'%s'/n",  
  62.              errno, strerror(errno));  
  63.   
  64.     bzero(buffer, MAXBUF + 1);  
  65.     strcpy(buffer, "这是客户端发给服务器端的消息/n");  
  66.     /* 发消息给服务器 */  
  67.     len = send(sockfd, buffer, strlen(buffer), 0);  
  68.     if (len < 0)  
  69.         printf  
  70.             ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'/n",  
  71.              buffer, errno, strerror(errno));  
  72.     else  
  73.         printf("消息'%s'发送成功,共发送了%d个字节!/n",  
  74.                buffer, len);  
  75.   
  76.     /* 关闭连接 */  
  77.     close(sockfd);  
  78.     return 0;  
  79. }  

编译程序用下列命令:
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
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值