inet_addr函数讲解

The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data in network byte order。

 inet_addr() 函数的作用是将点分十进制的IPv4地址转换成网络字节序列的长整型。


网络字节序定义:
收到的第一个字节被当作高位看待,这就要求发送端发送的第一个字节应当是高位。

上面两句话还是不太理解。

于是自己测试了一下 inet_addr(“192.168.2.80”)的返回值,其返回值为:1342351552,这是十进制的表示方法;

如果转换成2进制则为:‭01010000000000101010100011000000‬   (这个就是网络字节序)

如果将上面每8位二进制中间加个".",则变成‭01010000.00000010.10101000.11000000‬

再将上面的二进制再转回成十进制,则变成了80.2.168.192,会发现与上面的192.168.2.80是相反的,即如果原来的a.b.c.d,现在经过转换就变成了d.c.b.a;


我们看到规律了,其实如果一个数据包在网络上传输,肯定会有源目IP(二层数据包除外),要想中间的设备(如充当网关的路由器)或目标设备接收到这个数据包能正常解析出包的源目IP,那肯定得达成一个协议。

于是大家商量好了,要向表示a.b.c.d的IP地址,先将a对应对应的二进制发送出去(注:网络上传输的01字符串,即高低电平),接着是b、c、d,即从网络字节序的右端开始发。


发送端发送数据的时候是这么发送:

先发送

11000000‬  (对应的十进制为192)

再发送

10101000  (对应的十进制为168)

再发送

00000010.(对应的十进制为2)

最后发送

01010000  (对应的十进制为80)



接收端接受到数据是这样的:

先接收到第一个字节:

11000000‬ ,将其转回成十进制则为192


接收到第二个字节:

10101000 ,将其转换成十进制,则为168


接收到第三个字节:

00000010,将其转换成十进制,则为2


接收到第四个字节:

01010000,将其转换成为十进制,则为80


这样接收端接收到这32个字节,这么一组装,就变成了192.168.2.80。


综上,简单点说,如果一个为a.b.c.d的IP地址,在网络上传输,让接收端接收,也能正常解析成a.b.c.d的IP地址。那么,发送端应该

先将十进制的a转换成二进制发送出去(以8位为单位发送出去,不足八位的,左边补0);

再把十进制的b转换成二进制发送出去(以8位为单位发送出去,不足八位的,左边补0);

再把十进制的c转换成二进制发送出去(以8位为单位发送出去,不足八位的,左边补0);

最后把十进制的d转换成二进制发送出去(以8位为单位发送出去,不足八位的,左边补0)。









#include<stdio.h> #include<string.h> #include<stdlib.h> #include<netinet/tcp.h> #include<arpa/inet.h> #include<pthread.h> #include<unistd.h> #include<sys/socket.h> #include<errno.h> #include<fcntl.h> #define BUFFER_LENGTH 1024 void *client_routine(void *arg) { int clientfd = *(int *)arg; //获取客户端的id while (1) { char buffer[BUFFER_LENGTH] = {0}; int len = recv(clientfd,buffer,BUFFER_LENGTH,0); if(len< 0 ) { close(clientfd); break; } else if(len == 0) //disconnect 客户端断开连接 { close(clientfd); } else { printf("Recv:%s,%d byte(s)\n",buffer,len); } } int main(int argc,char *argv[]) { if(argc < 2) { printf("param Error\n"); return -1; } int port = atoi(argv[1]); int socketfd = socket(F_INET,SOCK_STREAM,0); struct sockaddr_in addr; //地址 memset(&addr,0,sizeof(struct sockaddr_in)); //把地址清空,避免遗留的脏数据 addr.sin_family= AF_INET; addr.sin_port = htons(port); //端口号 addr.sin_addr.s_addr = INADDR_ANY; if (bind(socketfd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in))<0) //绑定 { perror("bind"); return -2; } if(listen(socketfd,5)<0) { perror("listen"); return -3; } while(1) //一直检测是否有io连接 { struct sockaddr_in client_addr; //存储客户端地址 memset(&client_addr,0,sizeof(struct sockaddr_in)); socklen_t chlient_len = sizeof(client_addr); int clientfd = accept(socketfd,(struct sockaddr*)&client_addr,&client_len); //为请求安排服务员服务 pthread_t pthread_id; pthread_create(&thread_id,NULL,client_routine,&clientfd); } return 0; }
最新发布
04-02
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值