C++ IPv4与IPv6的兼容编码(转,出自http://blog.csdn.net/ligt0610/article/details/18667595)
这里不再对IPv6 socket相关编程的基础知识进行讲解,只提供一个IP协议无关的服务端和客户端的代码,仅供参考。
服务端代码:
- #include <iostream>
- #include <string>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <errno.h>
- #include <time.h>
- using namespace std;
- int tcp_listen(const char *host, const char *service, const int listen_num = 5)
- {
- int listenfd, ret;
- const int on = 1;
- struct addrinfo hints, *res, *ressave;
- bzero(&hints, sizeof(hints));
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_IP;
- if (0 != (ret = getaddrinfo(host, service, &hints, &res)))
- {
- cout << "getaddrinfo error: " << gai_strerror(ret) << endl;
- return -1;
- }
- ressave = res;
- while(NULL != res)
- {
- if (-1 == (listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
- {
- cout << "create socket error: " << strerror(errno) << endl;
- res = res->ai_next;
- continue;
- }
- if (-1 == setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
- {
- cout << "setsockopt error: " << strerror(errno) << endl;
- close(listenfd);
- res = res->ai_next;
- continue;
- }
- if (-1 == bind(listenfd, res->ai_addr, res->ai_addrlen))
- {
- cout << "bind error: " << strerror(errno) << endl;
- close(listenfd);
- res = res->ai_next;
- continue;
- }
- if (-1 == listen(listenfd, listen_num))
- {
- cout << "listen error: " << strerror(errno) << endl;
- close(listenfd);
- res = res->ai_next;
- continue;
- }
- break;
- }
- freeaddrinfo(ressave);
- if (NULL == res)
- return -1;
- return listenfd;
- }
- int get_addrinfo(const struct sockaddr *addr, string &ip, in_port_t &port)
- {
- void *numeric_addr = NULL;
- char addr_buff[INET6_ADDRSTRLEN];
- if (AF_INET == addr->sa_family)
- {
- numeric_addr = &((struct sockaddr_in*)addr)->sin_addr;
- port = ntohs(((struct sockaddr_in*)addr)->sin_port);
- }
- else if (AF_INET6 == addr->sa_family)
- {
- numeric_addr = &((struct sockaddr_in6*)addr)->sin6_addr;
- port = ntohs(((struct sockaddr_in6*)addr)->sin6_port);
- }
- else
- {
- return -1;
- }
- if (NULL != inet_ntop(addr->sa_family, numeric_addr, addr_buff, sizeof(addr_buff)))
- ip = addr_buff;
- else
- return -1;
- return 0;
- }
- int main(int argc, char *argv[])
- {
- int listenfd, connfd;
- struct sockaddr_storage cliaddr;
- socklen_t len = sizeof(cliaddr);
- time_t now;
- char buff[128];
- if (2 == argc) //指定端口
- listenfd = tcp_listen(NULL, argv[1]);
- else if (3 == argc) //指定本地IP和端口
- listenfd = tcp_listen(argv[1], argv[2]);
- else
- {
- cout << "usage: " << argv[0] << " [<hostname/ipaddress>] <service/port>" << endl;
- return -1;
- }
- if (listenfd < 0)
- {
- cout << "call tcp_listen error" << endl;
- return -1;
- }
- while (true)
- {
- connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &len);
- string ip = "";
- in_port_t port = 0;
- get_addrinfo((struct sockaddr*)&cliaddr, ip, port);
- cout << "client " << ip << "|" << port << " login" << endl;
- now = time(NULL);
- snprintf(buff, sizeof(buff) - 1, "%.24s", ctime(&now));
- write(connfd, buff, strlen(buff));
- close(connfd);
- }
- close(listenfd);
- return 0;
- }
客户端代码:
- #include <iostream>
- #include <string>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <errno.h>
- #include <time.h>
- using namespace std;
- int tcp_connect(const char *host, const char *service)
- {
- int sockfd, ret;
- struct addrinfo hints, *res, *ressave;
- bzero(&hints, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_IP;
- if (0 != (ret = getaddrinfo(host, service, &hints, &res)))
- {
- cout << "getaddrinfo error: " << gai_strerror(ret) << endl;
- return -1;
- }
- ressave = res;
- while (NULL != res)
- {
- if (-1 == (sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
- {
- cout << "create socket error: " << strerror(errno) << endl;
- res = res->ai_next;
- continue;
- }
- if (-1 == connect(sockfd, res->ai_addr, res->ai_addrlen))
- {
- cout << "connect error: " << strerror(errno) << endl;
- close(sockfd);
- res = res->ai_next;
- continue;
- }
- break;
- }
- freeaddrinfo(ressave);
- if (NULL == res)
- return -1;
- return sockfd;
- }
- int main(int argc, char *argv[])
- {
- int sockfd, n;
- char buff[128];
- struct sockaddr_storage cliaddr;
- if (3 != argc)
- {
- cout << "usage: " << argv[0] << " <hostname/ipaddress> <service/port>" << endl;
- return -1;
- }
- sockfd = tcp_connect(argv[1], argv[2]);
- if (sockfd < 0)
- {
- cout << "call tcp_connect error" << endl;
- return -1;
- }
- bzero(buff, sizeof(buff));
- while ((n = read(sockfd, buff, sizeof(buff) - 1) > 0))
- {
- cout << buff << endl;
- bzero(buff, sizeof(buff));
- }
- close(sockfd);
- return 0;
- }
编译:
g++ daytimesrv.cpp -o daytimesrv
g++ daytimecli.cpp -o daytimecli
运行举例:
服务端运行情况:
客户端运行情况:
以上客户端的请求与服务端的输出一一对应,客户端可以尝试用不同的IP去连接,然后观察服务端的输出,有助于理解底层的交互过程。
C++ IPv4与IPv6的兼容编码(转,出自http://blog.csdn.net/ligt0610/article/details/18667595)的更多相关文章
- Sublime Text3 离线安装Package Control并使用GBK编码 --转自https://blog.csdn.net/swhard/article/details/78930371
1.关闭Sublime Text 3,去https://github.com/wbond/package_control/releases下载一个zip包,我下载的是 2.将包内的顶层文件夹解压至C: ...
- 稀疏编码(Sparse Coding)的前世今生(一) 转自http://blog.csdn.net/marvin521/article/details/8980853
稀疏编码来源于神经科学,计算机科学和机器学习领域一般一开始就从稀疏编码算法讲起,上来就是找基向量(超完备基),但是我觉得其源头也比较有意思,知道根基的情况下,拓展其应用也比较有底气.哲学.神经科学.计 ...
- JavaScript在IE和Firefox(火狐)的不兼容问题解决方法小结 【转】http://blog.csdn.net/uniqer/article/details/7789104
1.兼容firefox的 outerHTML,FF中没有outerHtml的方法. 代码如下: if (window.HTMLElement) { HTMLElement.prototype.__de ...
- ubuntu16.04 tomcat7安装和编码修改(转发:https://blog.csdn.net/zl544434558/article/details/76735564)
有直接通过命令安装的,但是我还是喜欢把文件下载下来,然后自己配置. 1,下载tomcat7二进制文件 https://tomcat.apache.org/download-70.cgi 2,解压tom ...
- IPv4和IPv6的兼容问题
一网络拓扑 Ipv6网络1 路由器A IPv4网络 路由器B IPv6网络2 二知识补充 [注]双协议栈主机(路由器A.B)通过域名解析器区分传过来的是IPv4还是IPv6 三处理技术 双协议栈 Ip ...
- ios 兼容IPV4和IPV6网络通信
前言: 苹果官方出了新的规定,要求新上架的app都必须单独支持ipv6-only的网络. 准备工作: 搭建IPV6测试环境:http://blog.csdn.net/potato512/article ...
- VLC测试IPv4 IGMP/IPv6 MLD协议
1 简述 VLC既可以充当流客户端,又可以充当流服务器,并且可以跨平台使用,是一款开源.免费的软件,基于GNU GPL许可证. 2 搭建组播服务器 第一步:运行程序后选择“媒体 串流”:第二步:通过 ...
- [转载]Linux网络编程IPv4和IPv6的inet_addr、inet_aton、inet_pton等函数小结
转载:http://blog.csdn.net/ithomer/article/details/6100734 知识背景: 210.25.132.181属于IP地址的ASCII表示法,也就是字符串形式 ...
- Linux网络编程IPv4和IPv6的inet_addr、inet_aton、inet_pton等函数小结(转)
原文:http://blog.csdn.net/ithomer/article/details/6100734 知识背景: 210.25.132.181属于IP地址的ASCII表示法,也就是字符串形式 ...
随机推荐
- 第一百七十七节,jQuery,知问前端--概述及 jQuery UI
jQuery,知问前端--概述及 jQuery UI 学习要点: 1.项目介绍 2.jQuery UI 3.UI 主题 一.项目介绍 我们重点仿照“知乎”的架构模式来搭建界面和布局,以及大部分前端功能 ...
- 模式识别之概率分布---平均分布,正态分布,一阶滑动和,一阶线性回归 C语言编程
http://wenku.baidu.com/view/11cb1669a98271fe910ef9c6.html
- spark使用KryoRegistrator java代码示例
转载引用自:http://www.cnblogs.com/tovin/p/3833985.html 最近在使用spark开发过程中发现当数据量很大时,如果cache数据将消耗很多的内存.为了减少内存的 ...
- nginx访问css js 图片等静态资源,报404或无法定向访问到
配置完nginx,把php的项目放上去后,发现css,js和图片全部访问不到,一直重定向到根目录执行index.php,郁闷的在网上查了半天,原来不同后缀名的文件访问时都要在nginx.conf中声明 ...
- SQL.Cookbook 读书笔记4 插入更新和删除
第四章 插入更新和删除 4.1 插入数据 ,'PROGRA','NEW YOURK'); 4.2 从一个表向另一个表中复制 insert into dept_east(deptno,dname,loc ...
- 仿Windows制作TreeView数据加载
时间有限就直接贴源码吧,理解思路即可. 页面代码: <asp:TreeView ID="TreeViewLeft" runat="server" Show ...
- ID生成策略
在电商项目中,图片名.商品ID都要唯一且方便存储,于是记录下这两个ID生成策略的方法,以便日后项目再有需要.具体代码如下 import java.util.Random; /** * 图片名生成 */ ...
- 巨蟒python全栈开发django13:中间件部分
1.回顾昨日内容 2.session认证装饰器 3.django整个流程 4.中间件简单应用 5.简单统计访问次数 6.中间件其他方法 7.orm单表内容回顾
- 如何避免升级 Linux 实例内核后无法启动
如何避免升级 Linux 实例内核后无法启动_系统配置_操作运维 Linux_常见问题_云服务器 ECS-阿里云 https://help.aliyun.com/knowledge_detail/59 ...
- 客户端-服务器通信安全 sign key
API接口签名校验,如何安全保存appsecret? - 知乎 https://www.zhihu.com/question/40855191 要保证一般的客户端-服务器通信安全,可以使用3个密钥. ...