作者:huangguisu
使用TCP/IP协议进行网络应用开发的朋友首先要面对的就是对IP地址信息的处理。IP地址其实有三种不同的表示格式:
1)Ascii(网络点分字符串)-
2) 网络地址(32位无符号整形,网络字节序,大头)
3)主机地址 (主机字节序)
IP地址是IP网络中数据传输的依据,它标识了IP网络中的一个连接,一台主机可以有多个IP地址,IP分组中的IP地址在网络传输中将保持不变。下面具体介绍IP地址的三种不同表示格式。
一、点分10进制表示格式
这是我们最常见的表示格式,比如某机的IP地址可能为“202.101.105.66”。事实上,对于Ipv4(IP版本)来说,IP地址是由一个32位的二进制数所构成,但这样一串数字序列无疑是十分冗长并且难以阅读和记忆的。为了方便人们的记忆和使用,就将这串数字序列分成4组,每组8位,并改为用 10进制数进行表示,最后用小原点隔开,于是就演变成了“点分10进制表示格式”。 来看看刚才那个IP地址的具体转化过程: IP实际地址:11001010011001010110100101000010 分成4组后: 11001010 01100101 01101001 01000010 十进制表示: 202 101 105 66
点分表示: 202.101.105.66
二、网络字节顺序格式(NBO,Network Byte Order)
网络字节顺序格式和主机字节顺序格式一样,都只在进行网络开发中才会遇到。因此,在下面的介绍中,我假设读者对Socket编程知识有一定的基础。 在网络传输中,TCP/IP协议在保存IP地址这个32位二进制数时, 协议规定采用在低位存储地址中包含数据的高位字节的存储顺序(大头),这种顺序格式就被称为 网络字节顺序格式。在实际网络传输时,数据按照每32位二进制数为一组进行传输,由于存储顺序的影响, 实际的字节传输顺序是由高位字节到低位字节的传输顺序。 为了使通信的双方都能够理解数据分组所携带的源地址、目的地址以及分组的长度等二进制信息,无论是主机还是路由器,在发送每一个分组以前,都必须将二进制信息转换为TCP/IP标准的网络字节顺序格式。网络字节顺序格式的地址不受主机、路由器类型的影响,它的表示是唯一的。
在Socket编程开发中,通过函数inet_addr和inet_ntoa可以实现点分字符串与网络字节顺序格式IP地址之间的转换。 inet_addr函数原型如下:
代码语言:javascript复制 unsigned long inet_addr(const char FAR * cp)
函数中的参数cp指向网络中标准的点分地址字符串,其中每个以点分开的数字不可以大于255,这些数字可以是十进制、八进制、十六进制或者混合使用。如 “10.23.2.3”、“012.003.002.024”、“0xa.0x3.0x14.0x2”、“10.003.2.0x12”。
我们在前面的socket编程提到client端的代码,连接本地端口:
代码语言:javascript复制/* File Name: client.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define MAXLINE 4096
int main(int argc, char** argv)
{
int sockfd, n,rec_len;
char recvline[4096], sendline[4096];
char buf[MAXLINE];
struct sockaddr_in servaddr;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)n", strerror(errno),errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8000);
//可以使用:inet_pton(AF_INET, "127.0.0.1", servaddr.sin_addr);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//将字符串形式的IP地址转换为按网络字节顺序的整形值
connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) ;
printf("send msg to server: n");
fgets(sendline, 4096, stdin);
send(sockfd, sendline, strlen(sendline));
irec_len = recv(sockfd, buf, MAXLINE,0);
buf[rec_len] = '