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.sockadd
和sockaddr_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
使得sockaddr
和sockaddr_in
指標型別相互轉換;sin_port
和sin_addr
必須是網路位元組順序,因為它們被封裝在包的IP和UDP層,而sin_family
相關函式
1.socket()
函式
該函式用於根據指定的地址族、資料型別和協議來分配一個套接字的描述字及其所用的資源。Socket函式原型為:
int socket( int domain , int type , int protocol ) ;
a、 引數domain指定地址描述,一般為AP_INET
;
b、 引數type指定socket型別:SOCK_STREAM
和SOCK_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、addrlen
:sizeof( 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、addrlen
:sizeof( 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 |