目錄
?
1.昨天套接字服務器的弊端
2.如何通過多進程方式實現服務器并發
3.多進程服務器-1
4.多進程服務器-2
5.多進程版程序-回收子進程被信號中斷的處理
6.多線程版TCP服務處理思路
7.多線程并發服務器編寫
8.為什么不能把文件描述符地址傳到子線程中
9.多線程程序測試
?
1.昨天套接字服務器的弊端
```shell
# fast sender -> 客戶端
# slow recevicer -> 服務器端
# mss(Maximum Segment Size,單條數據最大長度)
# SYN: 請求建立連接
# ACK: OK
# FIN: 請求斷開連接
# win: 滑動窗口大小
###############################??三次握手 ###############################
第1步:
????客戶端:
????????1. 給服務器發送建立連接的請求 tcp協議中的 SYN 賦值為1
????????2. 0(0):?
????????????1). 第一個0: 客戶端生成的隨機序號
????????????2). 第二個0: 客戶端給服務器發送數據攜帶的數據量
????????3. win4096: 客戶端能夠緩存的最大數據量為 4k
????????4. mss 1460: 可處理的單條最大字節數1460
第2步:
????服務器:
????????1. ACK, 客戶端同意的客戶端的連接請求
????????2. 1 代表確認序號, 客戶端生成的隨機序號 + 接收的數據量
????????????- 0 + 1 = 1
?????????3. SYN: 服務器請求和客戶端建立連接
?????????4. 8000(0)
?????????????- 8000: 服務器端生成的隨機序號
?????????????- 0: 服務器給客戶端發送數據攜帶的數據量
?????????5. win 6144: 服務器端能夠緩存的最大數據量為6k
?????????6. mss 1024: 服務器端處理的單條數據最大長度 1k
?????????
第3步:
????客戶端:
????????1. ACK: 同意了服務器的連接請求
????????2. 8001: 確認序號 = 服務器生成的隨機序號 + 服務器給客戶端發送的字節數
????????????????8000 + 1 = 8001
????????3. win 4096: 現在客戶端可以緩存的最大數據量是4k
###############################??數據通信 ###############################
?
2.如何通過多進程方式實現服務器并發
第4步:
????客戶端給服務器發送數據:
????????1. 1(1024)
????????????1). 上一次的確認序號, 服務器回復給客戶端
?????????????????- 1代表次已經成功發送了1個字節, 這次發送的數據量是1024字節
????????2. 8001: 確認序號 = 服務器生成的隨機序號 + 服務器給客戶端發送的字節數
????????????????8000 + 1 = 8001
????????3. win 4096: 現在客戶端可以緩存的最大數據量是4k
第5,6,7,8,9 略, 參考第4步
????到第9步, 服務器接收數據的緩存被寫滿, 客戶端的發送被阻塞了
????
第10步:
????1. ack 6145: 確認序號, 客戶端發送給服務器的6145字節已經收到了
????????接收的實際字節數: 確認序號 - 生成的隨機序號
????2. win 2048: 告訴客戶端服務器的接收數據的緩存大小為2k
????????- 因為有2k數據被服務器端處理掉了
????????
第11步:
????1. ack 6145: 確認序號, 客戶端發送給服務器的6145字節已經收到了
????????接收的實際字節數: 確認序號 - 生成的隨機序號
????2. win 4096: 告訴客戶端服務器的接收數據的緩存大小為4k
????????- 因為有4k數據被服務器端處理掉了
?
3.多進程服務器-1
?
?```c
??// 主線程 -> 等待并接受客戶端的連接
??// 子線程 -> 建立連接之后處理通信的流程
??
??// 多個線程共用同一個虛擬地址空間
??共享資源:
??????- 堆區
??????-?全局數據區
??????-?文件描述符表
??獨享資源:
??????- 棧區
??????????
??// 線程資源釋放: 做線程分離
??```
??
??```c
??void* callback(void* arg)
??{
??????// 子線程的處理動作
??????while(1)
??????{
??????????// 通信
??????????int len = recv();
??????????if(len == 0)
??????????{
??????????????break;
??????????}
??????????send();
??????}
??}
??
??int main()
??{
??????int lfd = socket();
??????bind();
??????listen();
??????while(1)
??????{
??????????int cfd = accept();
??????????// 創建子線程
??????????pthread_create(&tid, NULL, callback, arg);
??????}
??}
??```
??
??
?
4.多進程服務器-2
?IP:?
??-?種類:
????-?局域網
??????-?192.168.xx.xx
????-?廣域網(公網)
??????-?88.99.1.34
??-?協議(網絡層)
????-?ipv4
??????-?4字節整數, 一般使用點分十進制字符串表示
????-?ipv6
??????-?16字節, 分成八份, 每份兩個字節
??-?作用:
????-?主機的家, 主機的地址, 通過ip就能找到網絡中的某臺主機
-?端口
??-?unsigned short
??-?作用: 定位主機上的一個進程
??-?只有需要網絡通信的進程才需要綁定端口
??-?取值范圍 0-65535
??-?使用, 通過瀏覽器進行服務器訪問:
????-?192.168.1.100:9999
-?域名:
??-?特殊的字符串, 需要和IP綁定, 成功之后才可以訪問服務器
??-?域名訪問-> 域名解析 -> 得到IP -> 通過IP訪問服務器?
-?字節序:
??-?數據在內存中的存儲順序, 單位是字節
??-?字符串沒有字節序問題
??-?分類:
????-?大端(網絡字節序)
??????-?高低, 低高
??????-?網絡通信的時候用大端
????????-?IP和端口
????????-?傳輸的數據 (如果是字符串就可以不轉換了)
????-?小端(主機字節序)??0x12345678
??????-?低低, 高高
??????-?我們使用的pc機默認是小端存儲
?
5.多進程版程序-回收子進程被信號中斷的處理
?基于tcp的通信流程
??-?服務器
????1.?創建監聽的套接字
???????int lfd = socket();
????2.?和本地的IP port綁定
???????bind();
????3.?設置監聽
???????listen()
????4.?阻塞等待客戶端連接
???????int cfd = accept();
?
6.多線程版TCP服務處理思路
?4.?阻塞等待客戶端連接
???????int cfd = accept();
????5.?通信
???????read/recv
???????write/send
????6.?關閉文件描述符
???????close()
??-?客戶端
????1.?創建通信的套接字
???????int cfd??=socket();
????2.?連接服務器, 通過服務器綁定的地址, 地址信息需要使用網絡字節序
???????connect();
????3.?通信
???????read/recv
???????write/send
????4.?關閉文件描述符
???????close();
?
7.多線程并發服務器編寫
?
8.為什么不能把文件描述符地址傳到子線程中
?