1. 两个结构体
1.1 sockaddr
-
kernel/include/linux/socket.h
-
struct sockaddr {
-
sa_family_t sa_family; //协议族: AF_XXX
-
char sa_data[14]; //14字节的端口号+地址
-
};
1.2 sockaddr_in
-
kernel/include/linux/in.h
-
struct in_addr {
-
__be32 s_addr; //4个字节: 255.255.255.255
-
};
-
-
struct sockaddr_in {
-
sa_family_t sin_family; //协议族: AF_XXX
-
__be16 sin_port; //2字节的端口号
-
struct in_addr sin_addr; //4字节的地址
-
};
sockaddr与sockaddr_in的排列都是: 2字节的端口+4字节的地址+8字节的pad
所以两者可以直接转换
2. 两个结构体的转换
-
char * sock_ntop(const struct sockaddr *sa, socklen_t salen)
-
{
-
char portstr[8];
-
static char str[128]; /* Unix domain is largest */
-
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
-
//只处理AF_INET: 先将4字节的数字地址转为字符串
-
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
-
return(NULL);
-
//再将2字节的数字端口号用snprintf转为字符串
-
if (ntohs(sin->sin_port) != 0) {
-
snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
-
strcat(str, portstr);
-
}
-
return(str);
-
}
sock_ntop的返回--> 127.0.0.1:52574
3. 分析
-
对sockaddr中的14字节打印如下:
-
for(i=0; i<14; i++)
-
dbmsg("%d= 0x%x",i, (unsigned char)pcliaddr->sa_data[i]);
-
-
udpserv.c:dg_echo[16]: 0= 0xb5
-
udpserv.c:dg_echo[16]: 1= 0xba
-
udpserv.c:dg_echo[16]: 2= 0x7f
-
udpserv.c:dg_echo[16]: 3= 0x0
-
udpserv.c:dg_echo[16]: 4= 0x0
-
udpserv.c:dg_echo[16]: 5= 0x1
-
udpserv.c:dg_echo[16]: 6= 0x0
-
udpserv.c:dg_echo[16]: 7= 0x0
-
udpserv.c:dg_echo[16]: 8= 0x0
-
udpserv.c:dg_echo[16]: 9= 0x0
-
udpserv.c:dg_echo[16]: 10= 0x0
-
udpserv.c:dg_echo[16]: 11= 0x0
-
udpserv.c:dg_echo[16]: 12= 0x0
-
udpserv.c:dg_echo[16]: 13= 0x0
-
其中 0xb5 0xba = b5ba=46522 --> client的端口号
-
7f 00 00 01--> 127.0.0.1 --> client的地址
阅读(1441) | 评论(0) | 转发(0) |