今天,說一下通訊端的域和地址族。前面linux的套介面和管道已經說到domain這個參數了,這個參數可以使AF_LOCAL.AF_LOCAL的首碼AF_表示地址族(address family),domain參數就是在選擇到底使用哪個地址族。
通用通訊端地址的結構:
struct sockaddr { sa_family_t sa_family;//地址族 char sa_data[14];//地址資料};
其中sa_family_t是一個無符號的短整數。整個資料佔16個位元組。
我們常見的domain參數一般是AF_INET(IPv4),AF_INET6(IPv6)。AF_INET的結構格式為:
#include <netinet/in.h>struct sockaddr_in { sa_family_t sin_family;//地址族 uint16_t sin_port;//連接埠號碼 struct in_addr sin_addr;//Inernet地址 unsigned char sin_zero[8];//佔位位元組};
說到網路位元組問題,就需要考慮到網路位元組序。因為位元組序有些系統是不同的。為了實現大端/小端位元組序之間的轉換,系統提供了幾個轉換函式:
#include <netinet/in.h>unsigned long htonl(unsigned long hostlong);unsigned short htons(unsigned short hostshort);unsigned long ntohl(unsigend long netlong);unsigned short ntohs(unsigned short netshort);
有了前面的介紹,可以開始初始化Internet地址了。下面的例子使用了到了socket()和bind()函數。
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <netinet/in.h>//error,用於輸出錯誤static void bail(const char *on_what){ perror(on_what); exit(1);}int main(){ int sck_inet = socket(AF_INET,SOCK_STREAM,0);//套介面,通訊端 if (sck_inet == -1) { bail("sock()"); } struct sockaddr_in adr_inet;//IPv4地址結構 memset(&adr_inet,0,sizeof adr_inet); adr_inet.sin_family = AF_INET; adr_inet.sin_port = htons(8081); const unsigned char IPno[] = {127,0,0,23}; memcpy(&adr_inet.sin_addr.s_addr,IPno,4); int len_inet = sizeof adr_inet; int z = bind(sck_inet, (struct sockaddr*)&adr_inet,len_inet);//綁定通訊端和ip地址 if (z == -1) { bail("bind()"); } system("netstat -pa --tcp 2>/dev/null | " "sed -n '1,/^Proto/p;/af_inet/p' "); close(sck_inet); return 0;}
今天的通訊端就介紹到這,下一篇要介紹的是地址轉換函式