簡體   English   中英

為什么在Socket Programming-C中將位移位8?

[英]Why shift bits by 8 in Socket Programming - C?

我正在研究《 FreeBSH開發人員手冊》,在那兒我看到了用於Socket編程的代碼:

struct sockaddr_in sa;
sa.sin_addr.s_addr = htonl((((((192 << 8) | 43) << 8) | 244) << 8) | 18);

為什么在這里使用“或”按位移位?

我知道按位移位和是什么,我做了一個很小的測試程序:

int c = 5;
printb(c);

int d = 5<<2;
printb(d);

int e = d | c;
printb(e);

打印:

00000000000000000000000000000101
00000000000000000000000000010100
00000000000000000000000000010101

但是我不明白為什么對於sa.sin_addr.s_addr我需要移動ip和/或使用以下值。 有人可以解釋嗎?

它正在創建IP 192.43.244.18的二進制表示形式。

讓我們逐一分析每個操作。

從這些常量的二進制表示形式開始:

192 = 11000000
 43 = 00101011
244 = 11110100
 18 = 00010010

最內在的操作:

(192 << 8) =

= 11000000 << 8 =

= 1100000000000000

下一個:

(192 << 8) | 43 =

= 1100000000000000 |
          00101011 =

  1100000000101011

下一個:

((192 << 8) | 43) << 8) =

= 1100000000101011 << 8 =

= 110000000010101100000000

下一個:

(((192 << 8) | 43) << 8) | 244 =

= 110000000010101100000000 | 244 =

= 110000000010101100000000 |
                  11110100 =

= 110000000010101111110100

下一個:

(((192 << 8) | 43) << 8) | 244) << 8 =

= 110000000010101111110100 << 8 =

= 11000000001010111111010000000000

最后:

(((((192 << 8) | 43) << 8) | 244) << 8) | 18 =

= 11000000001010111111010000000000 | 18 =

= 11000000001010111111010000000000 |
                          00010010 =

= 11000000001010111111010000010010

讓我們從查看sock_addr_in的實際結構sock_addr_in

#include <netinet/in.h>

struct sockaddr_in {
    short            sin_family;   
    unsigned short   sin_port;    
    struct in_addr   sin_addr;     
    char             sin_zero[8];  
};

in_addr的結構:

struct in_addr {
    unsigned long s_addr; 
};

現在,通常,當我們利用此s_addr時,我們這樣寫:

inet_aton("89.161.169.137", &myaddr.sin_addr.s_addr); //dummy ip

好。 我們去檢查inet_aton男人怎么樣?

inet_aton()將Internet主機地址cp從IPv4的數字和點表示法轉換為二進制形式(以網絡字節順序),並將其存儲在inp指向的結構中。 如果地址有效,則inet_aton()返回非零,否則返回零。

現在我們清楚地知道, unsigned long s_addr包含以網絡字節順序排列的ip的二進制形式。

您不需要移動ip youreslf,而只需使用inet_aton()和inet_ntoa()來處理ip地址。

首先,讓我們從二進制操作開始。 您正確假設的移位' a << << b '將a中的位沿左方向移動b量。 移位1可以看作是2的乘法。(實際上這是優化的方式,因為移位操作比乘法快,但是大多數現代編譯器都考慮到了這一點。)or語句為' a | b ' 。 在或中,如果兩個元素之一為1,則結果為1。這是在按位運算中使用的標准方法,實際上ab所有位都是或運算的。 例如a = 0010 1011,b = 1111 0000,a | b = 1111 1011。

現在回到問題所在。 在您的情況下, sa.sin_addr.s_addr開頭為0,因此在與192進行或運算時,會將192的位表示形式添加到變量中。 然后將其移位8位,以便為IP地址中的下一個元素釋放空間-每個元素的值都可以在0-255之間,也就是8位。 然后針對其余的片段重復此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM