一、使用信號量集實現進程間的通信
1.1 基本概念
(1)什麼是信號量???
信號量本質上就是一個計數器,用於控制同時訪問同一種共享資源的進程 / 線程個數;
- 如:
- 圖書館 Unix環境高級編程 5本 信號量 = 5
(2)信號量的工作方式
a. 首先初始化信號量爲最大值;
b. 當有進程申請到共享資源時,信號量的數值減1;
c. 當信號量的數值爲0時,申請共享資源的進程進入阻塞狀態;
d. 當有進程釋放共享資源時,信號量的數值加1;
e. 只要信號量的數值>0,則阻塞的進程可以繼續搶佔共享資源,搶佔不到的進程繼續阻塞;
(3)什麼是信號量集???
信號量集本質上就是由若干個信號量組成的集合,用於控制多種共享資源分別被同時訪問的進程 / 線程個數;
- 擴展:
- 信號量集:semaphore set
1.2 通信模型
(1)獲取key值,使用ftok();
(2)創建 / 獲取信號量集,使用semget();
(3)初始化 / 操作信號量集,使用semctl() / semop();
(4)如果不再使用,則刪除信號量集,使用semctl();
1.3 相關函數的解析
(1)semget()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
功能:
主要用於創建 / 獲取信號量集;
參數:
第一個參數:key值,ftok()的返回值;
第二個參數:信號量集的大小,也就是信號量的個數;
0 - - - - - - - - - - - - – 獲取已經存在的操作標誌
第三個參數:具體的操作標誌
IPC_CREAT - - - - - 若存在則打開,若不存在則創建
IPC_EXCL - - - - - - 與IPC_CREAT搭配使用,若存在則創建失敗
0 - - - - - - - - - - - - - -獲取已經存在的信號量集
返回值:
success —- 信號量集的ID,error —- -1;
注意:
當創建新的信號量集時,需要在第三個參數中通過按位或的方式指定權限信息,如:0664;
(2)semctl()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
功能:
主要用於控制參數指定的信號量集;
參數:
第一個參數:信號量集的ID,semget()的返回值;
第二個參數:信號量集的下標,從0開始;
第三個參數:具體的操作命令;
IPC_RMID - - - - - - 刪除信號量集,忽略第二個參數,不需要第四個參數
SETVAL - - - - - - - -使用第四個實參給下標爲semnum的信號量初始化
SETALL - - - - - - - -
第四個參數:可變長參數,是否需要取決於cmd;
(3)semop()
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, size_t nsops);
功能:
主要用於操作指定的信號量集;
參數:
第一個參數:信號量集的ID,semget()的返回值;
第二個參數:結構體指針,可以指向結構體變量,也可以指向結構體數組;
struct sembuf
{
unsigned short sem_num; /* 信號量集的下標 */
short sem_op; /* 信號量的操作:正數表示增加、負數表示減少、0表示不變 */
short sem_flg; /* 操作標誌,默認給0 */
}
第三個參數:結構體變量的個數;
當第二個參數指向結構體變量時,該參數的數值爲1
當第二個參數指向結構體數組時,該參數爲數組元素的個數
1.4 常用的基本命令
$ ipcs -s
- - - - - - 表示查看系統中已經存在的信號量集
$ ipcrm -s
- - - - - 信號量集的ID表示刪除指定的信號量集
$ ipcs -a
- - - - - - 表示查看系統中已經存在的所有IPC結構
二、網絡的基本常識
如:
目前主流的網絡通訊軟件:QQ 微信 飛信 阿里旺旺 …
2.1 七層網絡協議模型和常用的網絡協議
(1)七層網絡協議模型
爲了數據完整、安全地在網絡中傳遞,ISO將數據的傳遞從邏輯上劃分爲以下七層:
應用層 - - - - - - - - - 主要用於將數據提交給應用程序,如:QQ等;
表示層 - - - - - - - - - 主要用於按照統一的格式進行數據的封裝等;
會話層 - - - - - - - - - 主要用於控制對話的建立、關閉等操作;
傳輸層 - - - - - - - - - 主要用於進行數據的檢查和重新排序等;
網絡層 - - - - - - - - - 主要用於選擇具體網絡協議再次封裝和發送等;
數據鏈路層 - - - - – 主要用於將數據轉換爲高低電平信號等;
物理層 - - - - - - - - - 主要指交換機等網絡設備;
擴展:
IOS,即國際標準化組織(International Organization for Standardization)
(2)常用的網絡協議
a. TCP協議 (Transmission Control Protocol )
傳輸控制協議,是一種面向連接的協議,類似打電話;
b. UDP協議(User Datagram Protocol )
用戶數據報協議,是一種非面向連接的協議,類似寫信;
c. IP協議(Internet protocol )
互聯網協議,是上述兩種協議的底層協議;
2.2 IP地址和子網掩碼(重點)
(1)IP地址
- IP地址 - 是互聯網中的唯一地址標識,其本質上就是一個由32位二進制組成的整數(IPv4),也有128位二進制組成的整數(IPv6);
- 日常生活中採用點分十進制表示法來描述IP地址,也就是將每一個字節的二進制轉換爲一個十進制的整數,不同的整數之間採用小數點分隔;
爲了便於IP地址的管理,將IP地址分爲網絡地址和主機地址兩部分,根據IP地址中網絡地址和主機地址的位數不同分爲五類:
查看系統的IP地址的方式
windows系統:在dos窗口中使用命令ipconfig可以查看;
Linux系統:在終端中使用$ ifconfig
或者$ /sbin/ifconfig
(2)子網掩碼
主要用於劃分IP地址中的網絡地址和主機地址,以及判斷兩個IP地址是否在同一個子網中,具體的劃分方法爲:IP地址 & 子網掩碼 = 網絡地址 + 主機地址;
如:
IP地址:172.30.3.105 => 網絡地址:172.30.3.0
子網掩碼:255.255.255.0 主機地址:0.0.0.105
練習:
判斷以下兩個IP地址是否在同一個局域網中???
166.111.161.1與166.111.160.45
子網掩碼都是:255.255.254.0
2.3 端口號和字節序(重點)
(1)端口號
網絡編程中需要提供:IP地址 + 端口號;
IP地址 - - - - - - - 定位到具體的某一臺主機/設備;
端口號 - - - - - - - 定位到主機上的具體某個進程;
端口號本質上就是unsigned short類型,範圍是0~65535,其中0~1024之間的端口號被系統佔用,因此編程從1025開始使用;
(2)字節序
小端系統:主要指將低位數據存放在低位內存地址的系統;
大端系統:主要指將低位數據存放在高位內存地址的系統;
如:
對於數據0x12345678來說,不同的系統的存放形式如下:
小端系統按照地址從小到大:0x78 0x56 0x34 0x12
大端系統按照地址從小到大:0x12 0x34 0x56 0x78
一般性原則:
一般來說,對於所有發送到網絡中的多字節整數來說,先轉換爲網絡字節序再發送,而對於所有從網絡中接收過來的多字節整數來說,需要先轉換爲主機字節序再解析,而網絡字節序本質上就是大端系統的字節序;
三、基於socket的一對一通信模型
3.1 基本概念
socket本意爲“插座”,這裏指“邏輯通信載體”;
3.2 通信模型
主機A:
(1)創建socket,使用socket();
(2)準備通信地址,使用結構體類型;
(3)綁定socket和通信地址,使用bind();
(4)進行通信,使用read() / write();
(5)關閉socket,使用close();
主機B:
(1)創建socket,使用socket();
(2)準備通信地址,使用主機A的地址;
(3)連接socket和通信地址,使用connect();
(4)進行通信,使用read() / write();
(5)關閉socket,使用close();
練習:
查詢通信模型中的相關函數;
明日預報:
(1)網絡編程