1. 程式人生 > >2018-2019-1 20165201 《資訊安全系統設計基礎》第8周學習總結

2018-2019-1 20165201 《資訊安全系統設計基礎》第8周學習總結

2018-2019-1 20165201 《資訊安全系統設計基礎》第8周學習總結


學習內容總結

第11章 網路程式設計(劉念老師課上講過)

  TCP協議是面向連線的協議,它提供了一系列的資料糾錯功能,可以保證資料在網路上傳輸及時、無誤給接收方。因此面向連線協議的Socket程式設計模型應用最為廣泛,基於連線協議的服務是設計客戶端/伺服器應用程式時的標準。程式設計模型如圖所示

模型中,伺服器端的處理:
(1)使用socket系統呼叫,生成一個TCP協議模組與應用程式之間進行通訊的套接字;使用bind系統呼叫指定埠號;
(2)使用bind系統呼叫指定埠號;
(3)使用listen系統呼叫,指定連線接收佇列的長度,並等待來自客戶端的連線請求。
  前三步完成了啟動伺服器程式的工作。一旦listen監聽到有客戶端的連線,就呼叫accept接收連線。
  希望與伺服器通訊的程序稱為客戶,客戶所執行的計算機環境稱為客戶端,有時兩個概念混用。
  客戶端的處理:
(1)使用socket系統呼叫,開啟TCP協議模組與應用程式之間的通訊線路;
(2)使用connect系統呼叫,指定IP地址和埠號,和伺服器相應的服務應用程式建立TCP協議的連線請求;
  客戶端和伺服器程式在建立連線後,使用send和recv呼叫完成資料的傳送和接收工作。等待資料傳送結束後,各自呼叫close關閉套接字。
  使用TCP協議的Socket通訊程式包括服務程式和客戶程式。

基於C的Socket程式設計相關函式和資料型別
1.sockaddsockaddr_in結構:
sockaddr 結構

struct sockaddr  
{
    unsigned short sa_family;   /*地址族,AF_xxx有IPV4與IPV6等*/
    char        sa_data[14];    /*14位元組的協議地址*/
};

sa_family一般為AF_INET,表示Internet協議族,如是AF_UNIX表示UNIX協議簇;sa_data中包含該socket的IP地址和埠號。
in_add結構,用來儲存四位元組的IP地址

struct in_addr{
    unsigned long   s_addr;
};

sockaddr_in結構

struct sockaddr_in
{
    short int   sin_family;     /*地址族*/
    unsigned short int  sin_port;   /*埠號*/
    struct in_add       sin_addr;   /*IP地址*/
    unsigned char       sin_zero[8];    /*填充0以保持與struct sockaddr同樣大小*/
};

該結構中sin_zero使得sockaddrsockaddr_in指標型別相互轉換;sin_portsin_addr必須是網路位元組順序,因為它們被封裝在包的IP和UDP層,而sin_family

不傳送到網路上可以是本機位元組順序。

相關函式
1.socket()函式
  該函式用於根據指定的地址族、資料型別和協議來分配一個套接字的描述字及其所用的資源。Socket函式原型為:
int socket( int domain , int type , int protocol ) ;
a、 引數domain指定地址描述,一般為AP_INET
b、 引數type指定socket型別:SOCK_STREAMSOCK_DGRAM
c、引數protocol通常為0;
d、 函式返回值為一個整型socket描述符,在bind函式中呼叫。

2.bind()函式
  該函式用於將一個本地地址與一個套接字繫結在一起。
int bind( int sockfd , struct sockadd* my_addr , int addrlen) ;
a、sockfd:socket描述符,使用socket函式返回值,將該socket與本機上的一個埠相關聯。
在設計伺服器端程式是需要呼叫bind函式,以在該埠上監聽服務請求;而客戶端一般不需要呼叫bind函式,因為只需知道伺服器IP地址,並不關心客戶通過哪個埠與伺服器建立連線,核心會自動選擇一個未被佔用的埠供客戶端來使用。
b、my_addr:指向包含本機IP地址及埠號等資訊的sockaddr型別的指標。
c、addrlensizeof( struct sockaddr)的值。
d、bind函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼。

3.connect()函式
  與遠端伺服器建立一個TCP連線。
int connect(int sockfd, struct sockaddr* serv_addr, int addrlen);
a、sockfd:目的伺服器的socket描述符。
b、serv_addr:指向包含目的伺服器的IP地址及埠號的指標。
c、addrlensizeof( struct sockaddr)的值。
d、connect函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,進行伺服器端程式設計時不需呼叫connect函式。

4.listen()函式
  在伺服器端程式中,當socket與某一埠繫結後,需要監聽該埠,及時處理到達該埠上的服務請求。
int listen(int sockfd, int backlog);
a、sockfd:Socket系統呼叫返回的socket描述符。
b、backlog:指定在請求佇列中允許的最大請求數,進入的連線請求將在佇列中等待接收backlog限制了佇列中等待服務的請求數目,系統預設值為20。
c、listen函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼。

5.accept()函式
  當某個客戶端試圖與伺服器監聽的埠連線時,該連線請求將排隊等待伺服器用accept接收它併為其建立一個連線。
int accept(int sockfd, struct sockaddr* addr, int* addrlen);
a、sockfd:被監聽的socket描述符。
b、addr:sockaddr型別的指標變數,用來存放提出連線請求服務的主機資訊。
c、accept函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,如果沒有錯誤,accept()函式返回一個新想socket描述符,供這個新連線來實用,而伺服器可以繼續在以前的socket上監聽,同時可以在新的socket描述符上進行資料傳送和資料接收(sent()recv()操作)。

6.sent()recv()函式
  用於在面向連線(TCP)的socket上進行資料傳輸。
send()函式原型:
int send(int sockfd, const void* msg, int len, int flags) ;
a、sockfd:用於傳輸資料的socket描述符。
b、msg:是一個指向要傳送資料的指標。
c、len:以位元組為單位的資料的長度。
d、flags:一般情況下置為0。
e、函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,否則返回所傳送資料的總數,該數字可能小於len中所規定的大小。
recv()函式原型:
int recv(int sockfd, void* buf, int len, unsigned int flags);
a、sockfd:是接收資料的socket描述符。
b、buf:是存放接收資料的緩衝區。
c、len:以位元組為單位的緩衝區的長度。
d、flags:一般情況下置為0。
e、函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,無錯則返回讀入的位元組數,如果連線被中止,返回0。

7.endto()recvfrom()函式
  這兩個函式是利用資料報方式(UDP)進行資料傳輸。在無連線的資料報socket方式下,由於本地socket並沒有與遠端機器建立連線,所以在傳送資料時應指明目的地址。
sendto()原型:
int sendto(int sockfd, const void* msg, int len, unsigned int flags, const struct sockaddr* to, int tolen);
a、sockfd:用於傳輸資料的socket描述符。
b、msg:是一個指向要傳送資料的指標。
c、len:以位元組為單位的資料的長度。
d、flags:一般情況下置為0。
e、函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,否則返回所傳送資料的總數,該數字可能小於len中所規定的大小。
f、表示目的機器的IP地址和埠號。
g、tolen:被賦值為sizeof(struct sockaddr)
recvfrom函式原型:
int recv(int sockfd, void* buf, int len, unsigned int flags, struct sockaddr* from, int fromlen);
a、sockfd:是接收資料的socket描述符。
b、buf:是存放接收資料的緩衝區。
c、len:以位元組為單位的緩衝區的長度。
d、flags:一般情況下置為0。
e、函式返回值:為-1表示遇到錯誤,並且errno中包含相應的錯誤碼,無錯則返回讀入的位元組數,如果連線被中止,返回0。
f、from:儲存源機器的IP地址和埠號。
g、fromlen:常被賦值為sizeof(struct sockaddr)
當對於資料報socket呼叫了connect()函式時,也可以用send()recv()進行資料傳輸,但該socket仍然是資料報socket,並利用傳輸層的UDP服務。但是在傳送或接收資料報時,核心會自動為它加上目的地址和源地址資訊。

8.close()shutdown()函式
  當所有的資料操作結束後,可以呼叫close函式來釋放該socket資源,從而停止在該socket上的任何資料操作。
  也可以呼叫shutdown函式,允許只停止在某個方向上的資料傳輸,而另一個方向上的資料傳輸繼續進行。例如可以關閉某一個socket上的寫操作uo允許繼續在該socket上接收資料,直到讀入所有資料。
  但是,shutdown函式並不關閉套接字所佔用的所有資源,除非呼叫close函式來釋放。
看看兩個函式原型:
close(int sockfd);
shutdown(int sockfd, int how);
how引數的值和含義:
0:不允許繼續接收資料;
1:不允許繼續傳送資料;
2:不允許繼續傳送和接收資料。
shutdown在操作成功時返回0,錯誤時返回-1,並置errno值。

9.位元組順序轉換函式
htons():Host to Network Short的縮寫,該函式將主機的無符合短整型數字節順序轉換成網路位元組順序。
htonl():Host to Network Long的縮寫,該函式將主機的無符合長整型數字節順序轉換成網路位元組順序。
ntohs():Network to Host Short的縮寫,該函式將無符號短整型數從網路位元組順序轉換為主機位元組順序。
ntohl():Network to Host long的縮寫,該函式將無符號長整型數從網路位元組順序轉換為主機位元組順序。

第12章 併發程式設計

學習進度條

程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目標 2000行 20篇 200小時
第一週 83/83 1/1 8/8
第六週 75/158 2/3 10/18

參考資料