本人在作IOCP模型的編程時,
遇到一個問題
就是從SOCKADDR_STORAGE結構中,取出客戶的IP地址和端口,以利於統計
由於SOCKADDR_STORAGE結構比較複雜,並且兼容了IPV4和IPV6的版本,是直接取不出來的,
仔細研究"windows 網絡編程"中的代碼,意識到,無論怎麼樣,在收發消息的函數中,確定是要用到IP和Port信息的,
收發消息函數以下:
編程
1 |
rc=WSARecvFrom(sock->s,&wbuf,1,&bytes,&flags,(SOCKADDR*)&recvobj->addr,&recvobj->addrLen,&recvobj->ol,NULL); |
2 |
rc = WSASendTo(sock->s,&wbuf,1,&bytes,0,(SOCKADDR*)&sendobj->addr,sendobj->addrLen,&sendobj->ol,NULL); |
這兩個函數都用到告終構SOCKADDR,把SOCKADDR_STORAGE結構,強制轉換成了SOCKADDR結構,
而SOCKADDR結構以下:
windows
2 |
unsigned short sa_family; /* address family, AF_xxx */ |
3 |
char sa_data[14]; /* 14 bytes of protocol address */ |
而在個人意識中,好像還有一個結構與於幾乎是等價的,就是sockaddr_in結構,以下:
網絡
2 |
short int sin_family; /* Address family */ |
3 |
unsigned short int sin_port; /* Port number */ 此爲端口 |
4 |
struct in_addr sin_addr; /* Internet address */ 此爲IP地址, |
5 |
unsigned char sin_zero[8]; /* Same size as struct sockaddr */ |
看到上面的結構,勝利就在眼前了,再加把勁
函數
從上述結構得知,IP地址是以無符號長整型方式存儲的,可是在計算機中,是相似於"192.168.1.3"格式的
因此從sockaddr_in結構中取IP,確定有必定的函數,直接轉換過來,查找資料得知
inet_ntoa()函數實現上述格式,即"192.168.1.3"
而inet_addr()函數恰與它相反,即把"192.168.1.3"轉換爲無符號長整型.
以上都準備好了,就能夠進行轉換了,以下:
spa
1 |
SOCKADDR_STORAGE ssaddr; |
2 |
int rc=WSASendTo(sock->s,&wbuf,1,&bytes,0,(SOCKADDR*)&ssaddr,sendobj->addrLen,&sendobj->ol,NULL) |
此函數調用成功後,ssaddr中會被填入對方(即客戶)的IP地址和端口,
強制轉換後:
code
2 |
temp=inet_ntoa(((sockaddr_in*)((SOCKADDR*)&sendobj->addr))->sin_addr); |
或
orm
1 |
temp=inet_ntoa(((sockaddr_in*)&sendobj->addr)->sin_addr); |
取得端口的信息,方法同上ci