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)。









  • 18
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
讲解如下代码:#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <arpa/inet.h> #include <strings.h> #include <time.h> #include <string.h> #include <sys/time.h> #include <unistd.h> void print_time_usec() { struct tm* ptm; struct timeval time; gettimeofday(&time,NULL); ptm=localtime(&time.tv_sec); if (ptm!=NULL) { printf("%d-%d-%d:%d:%d:%d:%ld\n",ptm->tm_year+1900 ,ptm->tm_mon+1,ptm->tm_mday, ptm->tm_hour,ptm->tm_min,ptm->tm_sec, time.tv_usec%1000000/1000); } } void process_client(int connfd) { char recvbuf[100]; char sendbuf[100]; int num; //bzero(recvbuf,100); num=recv(connfd,recvbuf,100,0); recvbuf[num]='\0'; printf("recv:%s\n", recvbuf); sprintf(sendbuf,"welcome to server!"); send(connfd,sendbuf,strlen(sendbuf),0); close(connfd); } void process_accept(int listenfd) { int connfd; struct sockaddr_in client; int len=sizeof(client); connfd=accept(listenfd,(struct sockaddr*)&client,&len); if (connfd==-1) { perror("accept"); exit(1); } printf("connfd=%d\n",connfd); print_time_usec(); printf("client port:%d\n",client.sin_port); printf("client IP :%s\n", inet_ntoa(client.sin_addr)); process_client(connfd); } int main(int argc, char *argv[]) { int listenfd; struct sockaddr_in server; int SERVEPORT=1234,val=1; int backlog=5; listenfd=socket(AF_INET,SOCK_STREAM,0); if (listenfd==-1) { perror("socket"); exit(1); } printf("listenfd=%d\n",listenfd ); setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(char*)&val,sizeof(val) ); server.sin_family=AF_INET; server.sin_port=htons(SERVEPORT); server.sin_addr.s_addr=inet_addr("127.0.0.1"); bzero(&(server.sin_zero),8); if (bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1) { perror("bind"); exit(1); } if (listen(listenfd,backlog)==-1) { perror("listen"); exit(1); } process_accept(listenfd); close(listenfd); return 0; }
07-12

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值