LINUX IPV6 IPV4 兼容编程 HTTP SERVER 源代码讲解
更新时间:2023-10-25 17:39:01 阅读量: 综合文库 文档下载
- linux推荐度:
- 相关推荐
在网上看了很多资料,要不是长篇大论讲原理,要不就是直接贴代码,连个说明都没有,都不知道函数是干嘛的,下面这个代码直接就可以用,在一个同时有IPV4和IPV6地址的接口上,跑一个HTTP服务,这个兼容编程的办法实际上可以看出是把IPV4的地址转成了IPV6的地址
代码是在LINUX上运行的,WINSOCK的已经有人写了
IPV4转换范例 192.168.0.77 –》 ::ffff:192.168.0.77 ,将它打印出来以后去掉::ffff:就可以得到IPV4地址了
有些函数比如debug_printf什么的我就不贴了,太多了看不过来,重点看红色标注部分
int main() {
int listenfd=-1, connectfd;
pthread_t thread; //id of thread
struct ARG *arg; //pass this var to the thread char buf[BUFSIZE]; char temp[BUFSIZE];
debug_printf(\
int port=80;
debug_printf(\
memset(temp,0x0,BUFSIZE); sprintf(temp,\
//配置地址信息
struct addrinfo addrCriteria;
memset(&addrCriteria,0,sizeof(addrCriteria)); addrCriteria.ai_family=AF_UNSPEC; addrCriteria.ai_flags=AI_PASSIVE;
addrCriteria.ai_socktype=SOCK_STREAM; addrCriteria.ai_protocol=IPPROTO_TCP;
//获取地址信息,因为接口既有IPV6又有IPV4所以需要这个函数,一般都是inaddr_any struct addrinfo *server_addr;
int retVal=getaddrinfo(NULL,temp ,&addrCriteria,&server_addr); if(retVal!=0) {
debug_printf(\
}
struct addrinfo *addr=server_addr; //获取的地址是一个链表,实际上一般只是::的IPV6地址
while(addr!=NULL) {
//建立socket
listenfd=socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if(listenfd<0) continue;
//绑定端口和监听端口 int opt = SO_REUSEADDR;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));//可重用 fcntl(listenfd, F_SETFD, FD_CLOEXEC);
fcntl(listenfd, F_SETFL, O_NONBLOCK);//非阻塞
if((bind(listenfd,addr->ai_addr,addr->ai_addrlen)==0)&& listen(listenfd,128)==0) {
struct sockaddr_storage local_addr; socklen_t addr_size=sizeof(local_addr);
if(getsockname(listenfd,(struct sockaddr *)&local_addr,&addr_size)<0) {
debug_printf(\ }
debug_printf(\
PrintSocketAddress((struct sockaddr*)&local_addr); //一般是:: break; }
close(listenfd);
addr=addr->ai_next; }
freeaddrinfo(server_addr);
//其实上面都是废话,对于IPV4来说,inaddr_any就是0.0.0.0,对IPV6来说就是:: //但标准代码得这么写
if(listenfd<0) {
debug_printf(\ return ERROR; }
while(1) //MAIN LOOP {
//debug_printf(\
struct sockaddr_storage client_addr; //struct sockaddr_storage可以兼容IPV4 IPV6 socklen_t client_addrLen=sizeof(client_addr);
if((connectfd=accept(listenfd,(struct sockaddr *)&client_addr,&client_addrLen) ) <0) {
usleep(10000); continue; }
debug_printf(\
PrintSocketAddress((struct sockaddr*)&client_addr);
arg = (struct ARG *)malloc(sizeof(struct ARG)); memset(arg,0x0,sizeof(struct ARG)); arg->connfd = connectfd;
if(pthread_create(&thread, NULL, http_routine, (void*)arg))//这里就可以直接处理HTTP了,我就不贴了 {
debug_printf(\ continue; }
pthread_detach(thread);//detach the thread for recyle }
close(listenfd); return OK; }
//这个函数可以把CLIENT的地址打出来
void PrintSocketAddress(const struct sockaddr *address) {
// Test for address and stream if (address == NULL ) return;
void *numericAddress; // Pointer to binary address // Buffer to contain result (IPv6 sufficient to hold IPv4) char addrBuffer[INET6_ADDRSTRLEN]; in_port_t port; // Port to print
// Set pointer to address based on address family switch (address->sa_family) {
case AF_INET:
numericAddress = &((struct sockaddr_in *) address)->sin_addr; port = ntohs(((struct sockaddr_in *) address)->sin_port); break;
case AF_INET6: //其实根本不会是AF_INET,因为IPV4地址也会MAP成IPV6 numericAddress = &((struct sockaddr_in6 *) address)->sin6_addr; port = ntohs(((struct sockaddr_in6 *) address)->sin6_port); break; default:
debug_printf(\ // Unhandled type return; }
// Convert binary to printable address //
if (inet_ntop(address->sa_family, numericAddress, addrBuffer,sizeof(addrBuffer)) == NULL) {
debug_printf(\ } else {
debug_printf(\将可见地址打出来
if (port != 0) // Zero not valid in any socket addr debug_printf(\ } }
一些关键的INCLUDE
#include
结束语,从代码可以看出关键点是getaddrinfo 和 inet_ntop ,网上讲这2个函数的很多,但都不说如何使用,这个代码换掉一些函数和参数可以直接使用,WIN7访问HTTP IPV6的话先得有IPV6地址,自己配一个比如2001::100 ,找个LINUX(地址2001::101)跑这个代码,在浏览器上输入 http://[20001::101]:80 就可以访问了
正在阅读:
LINUX IPV6 IPV4 兼容编程 HTTP SERVER 源代码讲解10-25
广安府发〔2013〕 号10-08
2016-2022年中国水声定位系统行业市场分析及投资前景研究报告(目06-06
概率论与数理统计及其应用全部课后答案12-07
二年级下册的表内除法应用题03-30
2017高职语文二模试卷02-20
2013届杨浦区初三英语一模试卷及答案08-12
加强政治理论学习02-19
白色污染社会实践报告11-08
- 清真菜谱
- 我国国民经济和社会发展十二五规划纲要(全文)
- 高三物理机械振动和机械波复习2
- 浙江省公路山岭隧道机械化装备应用指导手册 doc - 图文
- 2018届高三数学文科二轮复习:专题检测(九) 导数的简单应用
- 2015年上海市公务员录用考试《行政职业能力测验》试卷(B类)
- 七年级道德与法制下册
- 大班户外游戏教案
- 病虫害预警 - 图文
- 某养鱼场为了提高经营管理水平
- 汉中市勉县尧柏余热汽机规程 10
- 烹饪试卷
- 事业单位考试公共基础知识专项分类题库训练
- 语文:第2课 走一步,再走一步 课堂导学案(人教版 七上)
- 天汉使用手册
- 人教版小学三年级数学下册教学计划
- 房地产销售管理完全操作手册122页
- 2009年评审通过具有中学高级教师专业技术资格人员名单...
- 《15秋公共关系学》作业1
- 2017最新版监理公司三标一体管理手册
- 源代码
- 兼容
- 讲解
- 编程
- SERVER
- LINUX
- IPV6
- IPV4
- HTTP
- 食品安全与日常饮食网课答案
- 2018南充市高考地理三月选择题训练(五)及答案
- 个体户可以不办税务登记证吗
- 读书笔记之4(政府绩效评价与政府会计)
- Lotus常见问题及解决方法
- 连续梁冬季施工方案 - 图文
- 消防三项报告备案表
- 青浦嘉民设计说明-0924
- 校园招聘综合能力测试题
- 临沂市数学中考试题分析(近三年)
- 关于乡镇查非纠违处置和责任追究实施办法
- 2019军转干公共基础知识管理常识:行政处罚与行政强制
- 集体备课4
- 2017年MPA考核体系专题深度分析报告 - 图文
- 社旗县人民医院食堂服务方案
- 2016湖北农村信用社考试历年真题汇总
- 徐州市2009年申报中学高级教师专业技术职务
- 东财17春秋学期《工程造价管理》在线作业三
- 初一(1)班家长会串词
- 写景抒情诗歌专题讲座