計算機網絡基礎之網絡編程套接字

IP地址(IP)

        IP地址是在IP協議中,用來標識網絡中不同主機的地址。IP協議有兩個版本,IPv與IPv6,在一般情況下默認的都是IPv4。對於IPv4來說,IP地址是一個無符號四字節32位的整數(uint32_t)。  IP地址是在傳輸層協議的報頭信息裏所包含的。

        在傳輸層的協議報頭中通常有兩個IP地址,分別是源IP地址(sip)和目的IP地址(dip),在網絡中傳輸時,兩個主機之間要進行通信,數據通過dip到達目的主機,而目的主機通過sip回覆源主機。

  

端口號(port)

        當數據到達目的主機後,數據就會從下自上依次交付,到最後的應用層應該交付給哪個應用呢?一個主機有很多網絡進程,每個網絡進程只能處理自己的網絡數據。這時候就需要一個東西來標識目的主機的目的網絡進程------>端口號

1、概念:端口號是一個2字節的16位整數,它類似於進程中的進程ID。端口號包含在傳輸層協議的報頭信息裏,並且在傳輸層協議的報頭信息裏有兩個端口號,一個是一個是源端口號(sport),一個是目的端口號(dport),目的是爲了兩主機之間更好的通信。

2、作用:端口號會在傳輸層協議嚮應用層交付的時候,告訴操作系統這個數據要交付給應用層的哪一個網絡進程。

3、在一臺主機上,一個端口號標記着唯一的一個網絡進程,但一個進程不一定對應一個端口號。對於不同的主機相同的進程,它們的端口號不一定是相同的。

 


網絡字節序:大端字節序

        我們知道所有數據在存儲的時候都有大端小端之分。而不同的機器其存儲方式也是不同的。那麼如果兩個主機在進行網絡通信的過程中,發送與接收數據,由於不清楚對方的主機是大端存儲還是小端存儲,那麼發送的數據的含義可能會被誤解。所以網絡數據流有大端小端之分。

大端字節序:低地址存高位      0x01(高地址) 02 03 04(低地址)--->0x01(低位)020304(高位)

小端字節序:低地址存低位      0x01(高地址) 02 03 04(低地址)--->0x04(低位)030201(高位)

        不同字節序的主機之間進行數據傳輸,將造成數據的逆序,所以爲了讓不同主機字節序的主機之間進行正常的網絡通信,在網絡間進行通信的時候必須使用大端字節序,也就意味着如果我們的主機是小端字節序,那麼通信的時候就需要對數據進行逆序。(逆序 主要針對的是在內存中存儲時,佔據大於1個字節的數據)

       主機字節序:當前主機的字節序,它的大小端取決於cpu架構。 ( x86---->小端)

       在進行網絡傳輸數據的時候,就需要將主機字節序與網絡字節序進行轉換。

#include <arpa/inet.h>

  • uint32_t htonl(uint32_t hostalong);
  • uint16_t htons(uint16_t hostalong);
  • uint32_t ntohl(uint32_t hostalong);
  • uint16_t ntohs(uint16_t hostalong);

   h:主機       n:網絡       hton:主機到網絡       l:32位長整數       s:16位短整數

        爲了保證代碼的可移植性,一般都需要調用這些函數去進行轉換。如果主機是小端的,那麼調用過後將參數轉成相應的大小端返回。如果是大端,那麼就不做任何事情。

 


網絡編程套接字

        我們知道:一個IP地址對應網絡中唯一的一個主機,一個端口號對應着一個主機上唯一的一個網絡進程。而IP地址加端口號就可以對應在網絡中唯一的一個網絡進程。此時我們就可以通過IP地址加端口號的形式來查找到網絡當中唯一的一個網絡進程,而IP地址加端口號的形式就叫做套接字

socket套接字編程:

      socket是操作系統提供的一套接口,目的是供用戶進行網絡通信編程

      網絡編程分爲客戶端程序和服務端程序,而客戶端是主動的一方,並且客戶端必須知道服務端的地址信息(ip+port/地址+端口),服務端也必須在這個指定的地址上進行等待。

     使用場景:主要是在傳輸層,因爲傳輸層有兩個典型協議:tcp/udp,具體選擇協議時要在進行數據傳輸時分情況而定。

  • tcp:面向連接,可靠傳輸,字節流服務。

                  優點:可靠傳輸,數據傳輸靈活;

                  缺點:傳輸速度較低,易 數據粘包(數據堆積造成數據粘連)

                  適用場景:針對數據安全性要求高的場景(文件傳輸等),保證數據的可靠性。

  • udp:無連接,不可靠,面向數據報  

                  優點:傳輸速度快,無數據粘包。

                  缺點:不可靠。

                  適用場景:針對數據安全性要求不是很高,但是實時性要求高的場景(視頻傳輸等),保證傳輸的速度。

 

socket編程操作:

  • socket常見API:socket API是一層抽象的網絡編程接口。

// 創建 socket 文件描述符 (TCP/UDP, 客戶端 + 服務器)
int socket(int domain, int type, int protocol);
// 綁定端口號 (TCP/UDP, 服務器)     
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
// 開始監聽socket (TCP, 服務器) 
int listen(int socket, int backlog);
// 接收請求 (TCP, 服務器) 
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
// 建立連接 (TCP, 客戶端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

  • sockaddr結構

         socket API是一層抽象的網絡編程接口,適用於各種底層網絡協議,如IPv4,IPv6。其中IPv4地址用sockaddr_in來表示,包括16爲地址類型,16位端口號和32爲IP地址。IPv4地址類型分別爲常數AF_INET與AF_INET6。

        socket API可以都用struct sockaddr*類型表示,在使用的時候需要強制轉化成sockaddr_in。

 


地址轉換函數 

        我們平常所看到的IP地址都是以點分十進制所表示的,而操作系統中對IP地址的看待都是二進制序列。並且sockaddr_in裏的IP地址也是二進制序列,所以我們在使用的時候就需要將點分十進制的與二進制序列進行轉化。

//點分十進制轉in_addr函數
#include <arpa/inet.h>
int inet_aton(const char* strptr, struct in_addr* addrptr);
in_addr_t inet_addr(const char* strptr);
int inet_pton(int family, const char* strptr, void* addrptr);

---------------------------------------------------------------------------------

//in_addr轉字符串的函數
char* inet_ntoa(struct in_addr inaddr);
const char* inet_ntop(int family, const void* addrptr, char* strptr, size_t len);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章