socket编程--sockaddr_in结构体操作
sockaddr結(jié)構(gòu)體
sockaddr的缺陷: struct sockaddr是一個(gè)通用地址結(jié)構(gòu),這是為了統(tǒng)一地址結(jié)構(gòu)的表示方法,統(tǒng)一接口函數(shù),使不同的地址結(jié)構(gòu)可以被bind(),connect()等函數(shù)調(diào)用;sa_data把目標(biāo)地址和端口信息混在一起了
| struct sockaddr { ? ?????unsigned short sa_family; char sa_data[14];?????????????????? };? |
| sa_family是通信類型,最常用的值是 "AF_INET" sa_data14字節(jié),包含套接字中的目標(biāo)地址和端口信息 |
sockaddr_in結(jié)構(gòu)體: struct sockaddr_in中的in表示internet,就是網(wǎng)絡(luò)地址,這只是我們比較常用的地址結(jié)構(gòu),屬于AF_INET地址族,它非常的常用。
sockaddr_in結(jié)構(gòu)體解決了sockaddr的缺陷,把port和addr分開儲(chǔ)存在兩個(gè)變量中
| struct sockaddr_in {? short int sin_family; unsigned short int sin_port;? ?????struct in_addr sin_addr;
?????unsigned char sin_zero[8]; }??? |
sin_port和sin_addr都必須是NBO,一般可視化的數(shù)字都是HBO(本機(jī)字節(jié)順序)
sin_zero初始值應(yīng)該使用函數(shù)bzero()來全部置零。
一般采用下面語句
| struct sockaddr_in cliaddr; bzero(&cliaddr,sizeof(cliaddr)); |
?sockaddr_in結(jié)構(gòu)體變量的基本配置
| struct sockaddr_in ina; |
sockaddr和sockaddr_in的相互關(guān)系,一般先把sockaddr_in變量賦值后,強(qiáng)制類型轉(zhuǎn)換后傳入用sockaddr做參數(shù)的函數(shù)。
1.sockaddr_in用于socket定義和賦值。
2.sockaddr用于函數(shù)參數(shù)
最典型的源、目的節(jié)點(diǎn)socket定義,對(duì)于源、目的地址和源、目的地址端口,需要建立兩個(gè)socket變量,cliaddr綁定源地址和源端口,servaddr用于connect和sendto的設(shè)定目的地址和目的端口。
struct sockaddr_in servaddr,cliaddr;create_socket(char *server_addr_string, unsigned int server_port) {//源socket賦值bzero(&cliaddr, sizeof(cliaddr));cliaddr.sin_family = AF_INET;//通常TCP/UDP協(xié)議源地址和端口都是隨機(jī)的cliaddr.sin_addr.s_addr = htons(INADDR_ANY);cliaddr.sin_port = htons(0);//目的socket賦值bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_aton(server_addr_string, &servaddr.sin_addr);servaddr.sin_port = htons(server_port); }網(wǎng)絡(luò)字節(jié)順序(Network Byte Order) NBO結(jié)構(gòu)體的sin_port和sin_addr都必須是NBO
本機(jī)字節(jié)順序(Host Byte Order) HBO一般可視化的數(shù)字都是HBO
NBO,HBO二者轉(zhuǎn)換
inet_addr() 將字符串點(diǎn)數(shù)格式地址轉(zhuǎn)化成無符號(hào)長(zhǎng)整型(unsigned long s_addr s_addr;)
inet_aton() 將字符串點(diǎn)數(shù)地址轉(zhuǎn)化成NBO
inet_ntoa() 將NBO地址轉(zhuǎn)化成字符串點(diǎn)數(shù)格式
htons() "Host to Network Short"
htonl() "Host to Network Long"
ntohs() "Network to Host Short"
ntohl() "Network to Host Long"
常用的是htons(),inet_addr()正好對(duì)應(yīng)結(jié)構(gòu)體的端口類型和地址類型
三種給socket賦值地址的方法
inet_aton(server_addr_string, &myaddr.sin_addr); myaddr.sin_addr.s_addr = inet_addr("132.241.5.10"); INADDR_ANY轉(zhuǎn)不轉(zhuǎn)NBO隨便 myaddr.sin_addr.s_addr = htons(INADDR_ANY); myaddr.sin_addr.s_addr = INADDR_ANY;另種給socket賦值端口的方法
#define MYPORT 3490 myaddr.sin_port = htons(MYPORT); 0(隨機(jī)端口)轉(zhuǎn)不轉(zhuǎn)NBO隨便 myaddr.sin_port = htons(0); myaddr.sin_port = 0;htons/l和ntohs/l等數(shù)字轉(zhuǎn)換都不能用于地址轉(zhuǎn)換,因?yàn)榈刂范际屈c(diǎn)數(shù)格式,所以地址只能采用數(shù)字/字符串轉(zhuǎn)換如inet_aton,inet_ntoa;唯一可以用于地址轉(zhuǎn)換的htons是針對(duì)INADDR_ANY
cliaddr.sin_addr.s_addr = htons(INADDR_ANY)
inet_addr()與inet_aton()的區(qū)別
inet_addr()是返回值型
struct sockaddr_in ina;
ina.sin_addr.s_addr = inet_addr("132.241.5.10");
inet_aton()是參數(shù)指針型
struct sockaddr_in ina;
inet_aton("132.241.5.10", &ina.sin_addr);
inet_ntoa將NBO地址轉(zhuǎn)化成字符串點(diǎn)數(shù)格式
參數(shù):結(jié)構(gòu)體變量.sinaddr
返回值:字符串指針
a1 = inet_ntoa(ina.sin_addr);
printf("address 1: %s\n", a1);
address 1:132.241.5.10
inet_addr()的缺陷:比如對(duì)-1做檢測(cè)處理
因?yàn)閕net_addr()的結(jié)果是整型,而發(fā)生錯(cuò)誤時(shí)返回-1.
而ina.sin_addr.s_addr是Unsigned long 型,
-1在long short顯示成111111111,和IP地址255.255.255.255相符合!會(huì)被誤認(rèn)廣播地址!
總結(jié)
以上是生活随笔為你收集整理的socket编程--sockaddr_in结构体操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web安全攻防从入门到放弃-记录
- 下一篇: nginx服务器的文件大小的限制解决方法