socket編程
- 1. 預備知識點
- 1.1 網絡字節序
- 1.2 ip地址轉換函數
- 1.3 sockaddr數據結構
- 最后
1. 預備知識點
1.1 網絡字節序
多字節數據有大端和小端之分,網絡數據流采用大端字節序,如果主機采用的是小端字節序,那么需要轉換。
- 大端:低地址存高字節,高地址存低字節,例如端口號為2048,為0x0800, 則在網絡中傳輸先發08,后發00
- 小端:低地址存低字節,高地址存高字節
#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
//這里h指host,n指net,l指四個字節數據的轉換,s指兩個字節的轉換
//比如端口轉換可以用兩個字節的轉換,ip可以用四個字節的函數轉換
查看本機字節序的方法,可以使用聯合體來判斷。其中聯合體成員設置為short類型和字符數組,然后給short類型賦值,然后查看字符數組的內容,就能知道本機的存儲字節序。
#include <stdio.h>union bytelist
{short cont;char chcon[sizeof(short)];
};int main()
{union bytelist byt;byt.cont = 0x0102;printf("byte content is [%d], store 00 is [0x%02d] store 01 is [0x%02d]\n",byt.cont,byt.chcon[0],byt.chcon[1]);//輸出 0201,說明低位數據存內存低位地址,高位數據存內存高位地址,小端存儲return 0;
}
1.2 ip地址轉換函數
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);參數:af:只能是這兩個 AF_INET or AF_INET6,分別代表ipv4和ipv6src:指源字符串或源ip地址dst:指目的字符串或目的ip地址size:指將ip轉成字符串的字符串大小
1.3 sockaddr數據結構
??以前使用sockaddr這個結構體,但是結構體成員區分不夠清晰,所以現在ipv4使用sockaddr_in代替它,這兩個內存占用大小是一樣的,只有內部成員變量有一點區別。
其中:
- sockaddr內存占用16個字節,16位地址類型(是ipv4還是ipv6),14字節的地址數據
- sockaddr_in內存占用16個字節,16位地址類型(是ipv4還是ipv6),16位端口號,32位ip地址,8字節空白填充
//sockaddr 結構體
struct sockaddr {sa_family_t sa_family; /* address family: AF_INET */char sa_data[14]; /* 14 bytes of protocol address */
};//sockaddr_in 結構體
struct sockaddr_in {sa_family_t sin_family; /* address family: AF_INET */in_port_t sin_port; /* port in network byte order */struct in_addr sin_addr; /* internet address */
};/* Internet address. */
struct in_addr {uint32_t s_addr; /* address in network byte order */
};
使用的時候轉換一下類型:
struct sockaddr_in servaddr;
/* initialize servaddr */
bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));
最后
推薦一個零聲教育學習教程,個人覺得老師講得不錯,分享給大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,
TCP/IP,協程,DPDK等技術內容,點擊立即學習:鏈接