- struct sockaddr {
- unsigned short sa_family;
- char sa_data[14];
- };
sockaddr_in和sockaddr結構的關係
填值的時候使用sockaddr_in結構,而作爲函數(如socket, listen, bind等)的參數傳入的時候轉換成sockaddr結構就行了,畢竟都是16個字符長。
上面是通用的socket地址,具體到Internet socket,用下面的結構,二者可以進行類型轉換 。
- struct sockaddr_in {
- short int sin_family; //指代協議簇,在socket編程中只能使用AF_INET
- unsigned short int sin_port; //端口號,使用網絡字節順序,因此要進行轉換
- struct in_addr sin_addr; //struct in_addr 是存儲ip地址,
- unsigned char sin_zero[8]; //這兒爲了讓sockaddr與sockaddr_in兩個數據結構保持大小相同而保留的空字節。
- };
- typedef struct in_addr{
- union{
- struct {unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b;
- struct{ unsigned short s_w1,s_w2;} S_un_w;
- struct{unsigned long S_addr;} S_un;
- }
- }IN_ADDR;
- /*sockadddr_in結構體用作bind、connect、recvfrom、sendto等函數的參數*/
- int sockfd;
- sockfd = socket(AF_INET, SOCK_STREAM, 0); //socket函數創建一個socket,並指定通信方式。
- struct sockaddr_in my_addr;
- /*爲此結構體賦值*/
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = htons(MYPORT); //採用htons函數轉換爲網絡字節序
- my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
- bzero(&(my_addr.sin_zero), 8);
- bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
關於上面程序中部分難點的講解。
(1)socket函數
函數原型: SOCKET socket(int af, int type, int protocal);
參數: af: 指代協議簇,在socket編程中只能使用AF_INET
type:爲新的socket指定傳輸類型。在windows scokets只能使用以下兩種類型
SOCK_STREAM 即TCP
SOCK_DGRAM即UDP
protocal:用於指定協議簇的特定協議,一般情況下賦值爲0 是正確的。
函數功能:socket函數產生一個socket描述符,並與所分配的資源相聯繫,和綁定特定的傳輸服務。
返回值:如果沒有錯誤發生,那麼socket函數將返回一個指向新socket的描述符。否則,一個INVALID_SOCKET 值返回。
(2)
主機字節序:
不同的CPU有不同的字節序類型,這些字節序是指整數在內存中保存的順序,這個叫做主機序。最常見的有兩種 1.Little endian:低字節存高地址,高字節存低地址 2.Big endian:低字節存低地址,高字節存高地址
網絡字節序:
網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序採用big endian排序方式。
爲了進行轉換bsd socket提供了轉換的函數,有下面四個網絡與主機字節轉換函數:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
htons 把unsigned short類型從主機序轉換到網絡序,htonl 把unsigned long類型從主機序轉換到網絡序,ntohs 把unsigned short類型從網絡序轉換到主機序,ntohl 把unsigned long類型從網絡序轉換到主機序。
在使用little endian的系統中 這些函數會把字節序進行轉換 在使用big endian類型的系統中這些函數會定義成空宏。
(3)
inet_addr()是將一個點分制的IP地址(如192.168.0.1)轉換爲上述結構中需要的32位IP地址(0xC0A80001)。