導航:首頁 > 網路問題 > 網路位元組次序代碼怎麼寫

網路位元組次序代碼怎麼寫

發布時間:2022-06-27 04:40:00

1. 什麼是網路位元組順序

網路位元組順序NBO(Network Byte Order):按從高到低的順序存儲,在網路上使用統一的網路位元組順序,可以避免兼容性問題。
這里一下給你解釋不清我下面給你發了 網路關於網路位元組順序的詳細介紹 你自己看看

2. 請問下python網路編程的位元組序怎麼處理

多謝樓上的,不是這么處理的python發送的都是二進制的string串,對數字類型的數據可以使用struct模塊來實現,具體例子如下:struct.pack('>l',
3)這里是輸出一個整數3,>表示使用網路位元組序,l表示數據類型

3. 網路位元組順序和機器順序什麼區別

存在兩種位元組順序:NBO與HBO
網路位元組順序NBO(Network Byte Order):
按從高到低的順序存儲,在網路上使用統一的網路位元組順序,可以避免兼容性問題。
主機位元組順序(HBO,Host Byte Order):
不同的機器HBO不相同,與CPU設計有關

計算機數據存儲有兩種位元組優先順序:高位位元組優先和低位位元組優先。Internet上數據以高位位元組優先順序在網路上傳輸,所以對於在內部是以低位位元組優先方式存儲數據的機器,在Internet上傳輸數據時就需要進行轉換。
我們要討論的第一個結構類型是:struct sockaddr,該類型是用來保存socket信息的:
struct sockaddr {
unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 位元組的協議地址 */ };
sa_family一般為AF_INET;sa_data則包含該socket的IP地址和埠號。
另外還有一種結構類型:
struct sockaddr_in {
short int sin_family; /* 地址族 */
unsigned short int sin_port; /* 埠號 */
struct in_addr sin_addr; /* IP地址 */
unsigned char sin_zero[8]; /* 填充0 以保持與struct sockaddr同樣大小 */
};
這個結構使用更為方便。sin_zero(它用來將sockaddr_in結構填充到與struct sockaddr同樣的長度)應該用bzero()或memset()函數將其置為零。指向sockaddr_in 的指針和指向sockaddr的指針可以相互轉換,這意味著如果一個函數所需參數類型是sockaddr時,你可以在函數調用的時候將一個指向 sockaddr_in的指針轉換為指向sockaddr的指針;或者相反。sin_family通常被賦AF_INET;sin_port和 sin_addr應該轉換成為網路位元組優先順序;而sin_addr則不需要轉換。
我們下面討論幾個位元組順序轉換函數:
htons()--"Host to Network Short" ; htonl()--"Host to Network Long"
ntohs()--"Network to Host Short" ; ntohl()--"Network to Host Long"
在這里, h表示"host" ,n表示"network",s 表示"short",l表示 "long"。
打開socket 描述符、建立綁定並建立連接
socket函數原型為:
int socket(int domain, int type, int protocol);
domain參數指定socket的類型:SOCK_STREAM 或SOCK_DGRAM;protocol通常賦值「0」。Socket()調用返回一個整型socket描述符,你可以在後面的調用使用它。
一旦通過socket調用返回一個socket描述符,你應該將該socket與你本機上的一個埠相關聯(往往當你在設計伺服器端程序時需要調用該函數。隨後你就可以在該埠監聽服務請求;而客戶端一般無須調用該函數)。 Bind函數原型為:
int bind(int sockfd,struct sockaddr *my_addr, int addrlen);
Sockfd是一個socket描述符,my_addr是一個指向包含有本機IP地址及埠號等信息的sockaddr類型的指針;addrlen常被設置為sizeof(struct sockaddr)。
最後,對於bind 函數要說明的一點是,你可以用下面的賦值實現自動獲得本機IP地址和隨機獲取一個沒有被佔用的埠號:
my_addr.sin_port = 0; /* 系統隨機選擇一個未被使用的埠號 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本機IP地址 */
通過將my_addr.sin_port置為0,函數會自動為你選擇一個未佔用的埠來使用。同樣,通過將 my_addr.sin_addr.s_addr置為INADDR_ANY,系統會自動填入本機IP地址。Bind()函數在成功被調用時返回0;遇到錯誤時返回「-1」並將errno置為相應的錯誤號。另外要注意的是,當調用函數時,一般不要將埠號置為小於1024的值,因為1~1024是保留埠號,你可以使用大於1024中任何一個沒有被佔用的埠號。
Connect()函數用來與遠端伺服器建立一個TCP連接,其函數原型為:
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
Sockfd是目的伺服器的sockt描述符;serv_addr是包含目的機IP地址和埠號的指針。遇到錯誤時返回-1,並且errno中包含相應的錯誤碼。進行客戶端程序設計無須調用bind(),因為這種情況下只需知道目的機器的IP地址,而客戶通過哪個埠與伺服器建立連接並不需要關心,內核會自動選擇一個未被佔用的埠供客戶端來使用。
Listen()——監聽是否有服務請求
在伺服器端程序中,當socket與某一埠捆綁以後,就需要監聽該埠,以便對到達的服務請求加以處理。
int listen(int sockfd, int backlog);
Sockfd是Socket系統調用返回的socket 描述符;backlog指定在請求隊列中允許的最大請求數,進入的連接請求將在隊列中等待accept()它們(參考下文)。Backlog對隊列中等待服務的請求的數目進行了限制,大多數系統預設值為20。當listen遇到錯誤時返回-1,errno被置為相應的錯誤碼。
故伺服器端程序通常按下列順序進行函數調用:
socket(); bind(); listen(); /* accept() goes here */
accept()——連接埠的服務請求。
當某個客戶端試圖與伺服器監聽的埠連接時,該連接請求將排隊等待伺服器accept()它。通過調用accept()函數為其建立一個連接,accept()函數將返回一個新的socket描述符,來供這個新連接來使用。而伺服器可以繼續在以前的那個 socket上監聽,同時可以在新的socket描述符上進行數據send()(發送)和recv()(接收)操作:
int accept(int sockfd, void *addr, int *addrlen);
sockfd是被監聽的socket描述符,addr通常是一個指向sockaddr_in變數的指針,該變數用來存放提出連接請求服務的主機的信息(某台主機從某個埠發出該請求);addrten通常為一個指向值為sizeof(struct sockaddr_in)的整型指針變數。錯誤發生時返回一個-1並且設置相應的errno值。
Send()和recv()——數據傳輸
這兩個函數是用於面向連接的socket上進行數據傳輸。
Send()函數原型為:
int send(int sockfd, const void *msg, int len, int flags);
Sockfd是你想用來傳輸數據的socket描述符,msg是一個指向要發送數據的指針。
Len是以位元組為單位的數據的長度。flags一般情況下置為0(關於該參數的用法可參照man手冊)。
char *msg = "Beej was here!"; int len, bytes_sent; ... ...
len = strlen(msg); bytes_sent = send(sockfd, msg,len,0); ... ...
Send()函數返回實際上發送出的位元組數,可能會少於你希望發送的數據。所以需要對send()的返回值進行測量。當send()返回值與len不匹配時,應該對這種情況進行處理。
recv()函數原型為:
int recv(int sockfd,void *buf,int len,unsigned int flags);
Sockfd是接受數據的socket描述符;buf 是存放接收數據的緩沖區;len是緩沖的長度。Flags也被置為0。Recv()返回實際上接收的位元組數,或當出現錯誤時,返回-1並置相應的errno值。
Sendto()和recvfrom()——利用數據報方式進行數據傳輸
在無連接的數據報socket方式下,由於本地socket並沒有與遠端機器建立連接,所以在發送數據時應指明目的地址,sendto()函數原型為:
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
該函數比send()函數多了兩個參數,to表示目地機的IP地址和埠號信息,而tolen常常被賦值為sizeof (struct sockaddr)。Sendto 函數也返回實際發送的數據位元組長度或在出現發送錯誤時返回-1。
Recvfrom()函數原型為:
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from是一個struct sockaddr類型的變數,該變數保存源機的IP地址及埠號。fromlen常置為sizeof (struct sockaddr)。當recvfrom()返回時,fromlen包含實際存入from中的數據位元組數。Recvfrom()函數返回接收到的位元組數或當出現錯誤時返回-1,並置相應的errno。
應注意的一點是,當你對於數據報socket調用了connect()函數時,你也可以利用send()和recv()進行數據傳輸,但該socket仍然是數據報socket,並且利用傳輸層的UDP服務。但在發送或接收數據報時,內核會自動為之加上目地和源地址信息。
Close()和shutdown()——結束數據傳輸
當所有的數據操作結束以後,你可以調用close()函數來釋放該socket,從而停止在該socket上的任何數據操作:close(sockfd);
你也可以調用shutdown()函數來關閉該socket。該函數允許你只停止在某個方向上的數據傳輸,而一個方向上的數據傳輸繼續進行。如你可以關閉某socket的寫操作而允許繼續在該socket上接受數據,直至讀入所有數據。
int shutdown(int sockfd,int how);
Sockfd的含義是顯而易見的,而參數 how可以設為下列值:
·0-------不允許繼續接收數據
·1-------不允許繼續發送數據
·2-------不允許繼續發送和接收數據,均為允許則調用close ()
shutdown在操作成功時返回0,在出現錯誤時返回-1(並置相應errno)。
DNS——域名服務相關函數
由於IP地址難以記憶和讀寫,所以為了讀寫記憶方便,人們常常用域名來表示主機,這就需要進行域名和IP地址的轉換。函數gethostbyname()就是完成這種轉換的,函數原型為:
struct hostent *gethostbyname(const char *name);
函數返回一種名為hosten的結構類型,它的定義如下:
struct hostent {
char *h_name; /* 主機的官方域名 */
char **h_aliases; /* 一個以NULL結尾的主機別名數組 */
int h_addrtype; /* 返回的地址類型,在Internet環境下為AF-INET */
int h_length; /*地址的位元組長度 */
char **h_addr_list; /* 一個以0結尾的數組,包含該主機的所有地址*/
};
#define h_addr h_addr_list[0] /*在h-addr-list中的第一個地址*/
2、將主機的unsigned long值轉換為網路位元組順序(32位):為什麼要這樣做呢?因為不同的計算機使用不同的位元組順序存儲數據。因此任何從Winsock函數對IP地址和埠號的引用和傳給Winsock函數的IP地址和埠號均時按照網路順序組織的。
&<60;&<60;&<60;&<60;&<60; u_long&<60; htonl(u_long hostlong);
&<60;&<60;&<60;&<60;&<60; 舉例:htonl(0)=0
&<60;&<60;&<60;&<60;&<60; htonl(80)= 1342177280
3、將unsigned long數從網路位元組順序轉換位主機位元組順序,是上面函數的逆函數。&<60;&<60;&<60;&<60;&<60;&<60; u_long&<60; ntohl(u_long netlong);
&<60;&<60;&<60;&<60;&<60; 舉例:ntohl(0)=0
&<60;&<60;&<60;&<60;&<60; ntohl(1342177280)= 80
1342177280 = 80*256*256*256

4、將主機的unsigned short值轉換為網路位元組順序(16位):原因同2:&<60;&<60;&<60;&<60;&<60;&<60; u_short&<60; htons(u_short hostshort);
&<60;&<60;&<60;&<60;&<60; 舉例:htonl(0)=0
&<60;&<60;&<60;&<60;&<60; htonl(80)= 20480
5、將unsigned short數從網路位元組順序轉換位主機位元組順序,是上面函數的逆函數。&<60;&<60;&<60;&<60;&<60;&<60; u_short&<60; ntohs(u_short netshort);
&<60;&<60;&<60;&<60;&<60; 舉例:ntohs(0)=0
&<60;&<60;&<60;&<60;&<60; ntohsl(20480)= 80
20480 = 8-*256 (大小端地址轉換)

****
不同的CPU有不同的位元組序類型 這些位元組序是指整數在內存中保存的順序 這個叫做主機序
最常見的有兩種
1. Little endian:將低序位元組存儲在起始地址
2. Big endian:將高序位元組存儲在起始地址

LE little-endian
最符合人的思維的位元組序
地址低位存儲值的低位
地址高位存儲值的高位
怎麼講是最符合人的思維的位元組序,是因為從人的第一觀感來說
低位值小,就應該放在內存地址小的地方,也即內存地址低位
反之,高位值就應該放在內存地址大的地方,也即內存地址高位

BE big-endian
最直觀的位元組序
地址低位存儲值的高位
地址高位存儲值的低位
為什麼說直觀,不要考慮對應關系
只需要把內存地址從左到右按照由低到高的順序寫出
把值按照通常的高位到低位的順序寫出
兩者對照,一個位元組一個位元組的填充進去

4. unix C語言網路位元組序 怎麼定義啊 舉個例子 是用char還是什麼

網路位元組序都是大端,你可以使用如下函數處理
uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

5. 網路位元組序與主機位元組序

不同的CPU有不同的位元組序類型
這些位元組序是指整數在內存中保存的順序
這個叫做主機序
最常見的有兩種
1.
Little
endian:將低序位元組存儲在起始地址
2.
Big
endian:將高序位元組存儲在起始地址
LE
little-endian
最符合人的思維的位元組序
地址低位存儲值的低位
地址高位存儲值的高位
怎麼講是最符合人的思維的位元組序,是因為從人的第一觀感來說
低位值小,就應該放在內存地址小的地方,也即內存地址低位
反之,高位值就應該放在內存地址大的地方,也即內存地址高位
BE
big-endian
最直觀的位元組序
地址低位存儲值的高位
地址高位存儲值的低位
為什麼說直觀,不要考慮對應關系
只需要把內存地址從左到右按照由低到高的順序寫出
把值按照通常的高位到低位的順序寫出
兩者對照,一個位元組一個位元組的填充進去
例子:在內存中雙字0x01020304(DWORD)的存儲方式
內存地址
4000
4001
4002
4003
LE
04
03
02
01
BE
01
02
03
04
例子:如果我們將0x1234abcd寫入到以0x0000開始的內存中,則結果為
big-endian
little-endian
0x0000
0x12
0xcd
0x0001
0x23
0xab
0x0002
0xab
0x34
0x0003
0xcd
0x12
x86系列CPU都是little-endian的位元組序.
大端小端轉換方法:
Big-Endian轉換成Little-Endian如下:
#define
BigtoLittle16(A)
((((uint16)(A)
&
0xff00)
>>
8)
|
(((uint16)(A)
&
0x00ff)
<<
8))
#define
BigtoLittle32(A)
((((uint32)(A)
&
0xff000000)
>>
24)
|
(((uint32)(A)
&
0x00ff0000)
>>
8)
|
(((uint32)(A)
&
0x0000ff00)
<<
8)
|
(((uint32)(A)
&
0x000000ff)
<<
24))
大端小端檢測方法:
如何檢查處理器是big-endian還是little-endian?
聯合體union的存放順序是所有成員都從低地址開始存放,利用該特性就可以輕松地獲得了CPU對內存採用Little-endian還是Big-endian模式讀寫。
int
checkCPUendian()
{
union
{
unsigned
int
a;
unsigned
char
b;
}c;
c.a
=
1;
return
(c.b
==
1);
}
網路位元組順序
網路位元組順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網路位元組順序採用big
endian排序方式。
為了進行轉換
bsd
socket提供了轉換的函數
有下面四個
htons
把unsigned
short類型從主機序轉換到網路序
htonl
把unsigned
long類型從主機序轉換到網路序
ntohs
把unsigned
short類型從網路序轉換到主機序
ntohl
把unsigned
long類型從網路序轉換到主機序
在使用little
endian的系統中
這些函數會把位元組序進行轉換
在使用big
endian類型的系統中
這些函數會定義成空宏
同樣
在網路程序開發時
或是跨平台開發時
也應該注意保證只用一種位元組序
不然兩方的解釋不一樣就會產生bug.

6. 網路編程是為什麼要考慮位元組序問題

CPU(對 就是CPU)不同 位元組序不同的

什麼是位元組序
位元組序,顧名思義位元組的順序,再多說兩句就是大於一個位元組類型的數據在內存中的存放順序(一個位元組的數據當然就無需談順序的問題了)。其實大部分人在實際的開 發中都很少會直接和位元組序打交道。唯有在跨平台以及網路程序中位元組序才是一個應該被考慮的問題。
在所有的介紹位元組序的文章中都會提到字 節序分為兩類:Big-Endian和Little-Endian,引用標準的Big-Endian和Little-Endian的定義如下:
a) Little-Endian就是低位位元組排放在內存的低地址端,高位位元組排放在內存的高地址端。
b) Big-Endian就是高位位元組排放在內存的低地址端,低位位元組排放在內存的高地址端。
c) 網路位元組序:TCP/IP各層協議將位元組序定義為Big-Endian,因此TCP/IP協議中使用的位元組序通常稱之為網路位元組序。

Big-Endian
計算機體系結構中一種描述多位元組存儲順序的術語,在這種機制中最重要位元組(MSB)存放在最低端的地址 上。採用這種機制的處理器有IBM3700系列、PDP-10、Mortolora微處理器系列和絕大多數的RISC處理器。

Little-Endian
計算機體系結構中 一種描述多位元組存儲順序的術語,在這種機制中最不重要位元組(LSB)存放在最低端的地址上。採用這種機制的處理器有PDP-11、VAX、Intel系列 微處理器和一些網路通信設備。該術語除了描述多位元組存儲順序外還常常用來描述一個位元組中各個比特的排放次序。

除了Big-Endian和Little-Endian之外的多位元組存儲順序就是Middle- Endian,比如以4個位元組為例:象以3-4-1-2或者2-1-4-3這樣的順序存儲的就是Middle-Endian。這種存儲順序偶爾會在一些小 型機體系中的十進制數的壓縮格式中出現。

7. G,GB,KB,MB,位元組;怎麼換算他們的大小順序是怎麼排的

一個漢字為2B
1024B=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB

8. 怎麼將字元串進行網路位元組序轉換 示例

現在一般使用inet_aton和inet_ntoa來處理網路位元組和主機位元組之間的轉換;

有兩個更新的函數inet_pton和inet_ntop這2個函數能夠處理ipv4和ipv6,原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);

這個函數轉換字元串到網路地址,第一個參數af是地址族,轉換後存在dst中
inet_pton 是inet_addr的擴展,支持的多地址族有下列:

AF_INET
src為指向字元型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函數將該地址
轉換為in_addr的結構體,並復制在*dst中

AF_INET6
src為指向IPV6的地址,,函數將該地址
轉換為in6_addr的結構體,並復制在*dst中
如果函數出錯將返回一個負值,並將errno設置為EAFNOSUPPORT,如果參數af指定的地址族和src格式不對,函數將返回0。
函數inet_ntop進行相反的轉換原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
這個函數轉換網路二進制結構到ASCII類型的地址,參數的作用和上面相同,只是多了一個參數socklen_t cnt,他是所指向緩存區dst的大小,避免溢出,如果緩存區太小無法存儲地址的值,則返回一個空指針,並將errno置為ENOSPC

9. 字數據書寫順序與機器碼順序

我想您問的是網路位元組順序和機器順序什麼區別?
有兩種位元組順序,網路位元組順序NBO(NetworkByteOrder)和主機位元組順序(HBO,HostByteOrder)。計算機數據存儲有兩種位元組優先順序:高位位元組優先和低位位元組優先。
Internet上數據以高位位元組優先順序在網路上傳輸,所以對於在內部是以低位位元組優先方式存儲數據的機器,在Internet上傳輸數據時就需要進行轉換。

10. C/C++ 網路編程位元組序的問題

恩。基本上是這個意思。
htons表示short類型的數據由主機位元組序轉為網路位元組序。而ntohs表示是網路位元組序轉換到主機位元組序。
因為歷史的原因網路位元組序約定為大端(bigedian),而主機位元組序位則依據CPU的類型各有不同,我們普通的intel處理器為小端,而powerpc等一些處理器則是大端。那麼從主機出去的數據到網路上例如是INTEL,那是要轉換的。所以你這個無論是伺服器還是客戶端,只要是出去的數據都是要經過htonxx這樣的函數轉換。如果是接收呢,則是要通過ntohxx這樣的函數轉換的。
設置埠由於是面向網路操作,所以也是要使用htons轉換的。

閱讀全文

與網路位元組次序代碼怎麼寫相關的資料

熱點內容
網路共享中心沒有網卡 瀏覽:527
電腦無法檢測到網路代理 瀏覽:1377
筆記本電腦一天會用多少流量 瀏覽:598
蘋果電腦整機轉移新機 瀏覽:1381
突然無法連接工作網路 瀏覽:1081
聯通網路怎麼設置才好 瀏覽:1230
小區網路電腦怎麼連接路由器 瀏覽:1059
p1108列印機網路共享 瀏覽:1215
怎麼調節台式電腦護眼 瀏覽:721
深圳天虹蘋果電腦 瀏覽:957
網路總是異常斷開 瀏覽:618
中級配置台式電腦 瀏覽:1018
中國網路安全的戰士 瀏覽:638
同志網站在哪裡 瀏覽:1422
版觀看完整完結免費手機在線 瀏覽:1464
怎樣切換默認數據網路設置 瀏覽:1114
肯德基無線網無法訪問網路 瀏覽:1290
光纖貓怎麼連接不上網路 瀏覽:1501
神武3手游網路連接 瀏覽:969
局網列印機網路共享 瀏覽:1005