Socket():創建套接字 Bind():綁定套接字。將一個本地協議地址賦予一個套接字 Listen():監聽套接字 Connect():建立與伺服器之間的連接。 accept():接收連接, Send():發送函數 recv():接收函數 close():關閉連接 伺服器端順序: Socket( ...
Socket():創建套接字
Bind():綁定套接字。將一個本地協議地址賦予一個套接字
Listen():監聽套接字
Connect():建立與伺服器之間的連接。
accept():接收連接,
Send():發送函數
recv():接收函數
close():關閉連接
伺服器端順序:
Socket(),bind(),listen(),accept(),recv(),close()
客戶端順序:
Socket(),connect(),send(),close()
socket():創建套接字,返回一個小整數描述符,以後所有的函數調用就用該描述符來標識這個套接字。 返回值小於0,則創建套接字失敗 AF_XX地址族 PF_XX協議族
socket( int af, int type, int protocol);
af: 一個地址描述。目前僅支持AF_INET格式,也就是說ARPA Internet地址格式。
type: 指定socket類型。新套介面的類型描述類型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。常用的socket類型 有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol: 顧名思義,就是指定協議。套介面所用的協議。如調用者不想指定,可用0。常用的協議有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它們分別對應TCP傳輸協議、UDP傳輸協議、STCP傳輸協議、TIPC傳輸協議。
inet_pton():IP地址轉換函數,可以在將IP地址在"點分十進位"和"二進位整數"之間轉換
而且,inet_pton和inet_ntop這2個函數能夠處理ipv4和ipv6。
int inet_pton(int af,const char*src,void*dst);
這個函數轉換字元串到網路地址,第一個參數af是地址族,第二個參數*src是來源地址,第三個參數*dst接收轉換後的數據。
inet_pton是inet_addr的擴展,支持的多地址族有下列:
af=AF_INET
src為指向字元型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函數將該地址轉換為in_addr的結構體,並複製在*dst中。
af=AF_INET6
src為指向IPV6的地址,函數將該地址轉換為in6_addr的結構體,並複製在*dst中。
如果函數出錯將返回一個負值,並將errno設置為EAFNOSUPPORT,如果參數af指定的地址族和src格式不對,函數將返回0。
fork(): pid_t fork(void); 在子進程中返回0,在父進程中返回子進程的ID,若出錯返回-1。
Fork在子進程返回0而不是父進程的ID原因是:任何子進程都只有一個父進程,且子進程可以通過調用getppid取得父進程的進程ID。相反,父進程可以有許多子進程,而且無法獲取各個子進程的ID號,如果父進程想要跟蹤所有子進程的進程ID,那麼它必須記錄每次調用fork的返回值。
會創建一個父進程的副本,兩者同時運行,先後順序不確定
vfork():
1.vfork保證子進程先運行,在它調用exec或exit之後父進程才可能被調度運行。如果在調用這兩個函數之前子進程依賴於父進程的進一步動作,則會導致死鎖。
2.fork要拷貝父進程的進程環境;而vfork則不需要完全拷貝父進程的進程環境,在子進程沒有調用exec和exit之前,子進程與父進程共用進程環境,相當於線程的概念,此時父進程阻塞等待。
為什麼會有vfork呢?
因為以前的fork當它創建一個子進程時,將會創建一個新的地址空間,並且拷貝父進程的資源,然後將會有兩種行為:
1.執行從父進程那裡拷貝過來的代碼段
2.調用一個exec執行一個新的代碼段
當進程調用exec函數時,一個新程式替換了當前進程的正文,數據,堆和棧段。這樣,前面的拷貝工作就是白費力氣了,這種情況下,聰明的人就想出了vfork。vfork並不複製父進程的進程環境,子進程在父進程的地址空間中運行,所以子進程不能進行寫操作,並且在兒子“霸占”著老子的房子時候,要委屈老子一下了,讓他在外面歇著(阻塞),一旦兒子執行了exec或者exit後,相當於兒子買了自己的房子了,這時候就相當於分家了。
因此,如果創建子進程是為了調用exec執行一個新的程式的時候,就應該使用vfork
線程:一個程式至少有一個進程,一個進程至少有一個線程。
線程是進程的一個實體,是CPU進行調度的最小單位。
幾個函數:
pthread_mutex_lock(&mutex); //加鎖
pthread_mutex_unlock(&mutex); //釋放鎖
pthread_cond_wait(&cond, &mutex); //條件等待 進入此語句將加鎖進行釋放
pthread_cond_signal(&cond); //激活條件
pthread_cond_broadcast(&cond); // 廣播 激活所有滿足此條件的
pthread_create(&tid[i-1], NULL, thread_fun, &i); //創建線程
pthread_join(tid[i], NULL); //等待線程結束
線程的同步與互斥
多線程共用一個進程的地址空間雖然線程間通信容易進行,但是多線程同時訪問共用對象時需要引入同步和互斥機制。
同步指的是多個任務按照約定的順序相互配合完成一件事情,dijkstra基於信號量的概念提出了一種同步機制。由信號量來決定線程是繼續運行還是阻塞等待。
線程間的互斥,引入互斥鎖的目的是用來保證共用資源數據操作的完整性。
互斥鎖主要用來保護臨界資源
每個鄰居資源都由一個互斥鎖來保護,任何時刻最多只能有一個線程能訪問該資源。
線程必須先獲得互斥鎖才能訪問臨界資源,訪問完臨界資源後釋放該鎖。如果無法獲得鎖,線程會阻塞知道獲得鎖為止。
互斥鎖和條件變數實現讀寫鎖:讀寫鎖的讀和寫是互斥的,讀的時候不能寫,寫的時候不能讀,但如果實現讀寫鎖的話,首先要確定的的是讀優先還是寫優先。還有就是讀進程可以共存,寫進程則完全互斥。如果有進程需要寫時,要申請寫鎖,但如果在申請寫鎖的時候發現有其他進程正在寫或者正在讀,則進行等待,一直等到讀鎖或寫鎖完全釋放為止。讀進程在讀取時先申請讀鎖,若此時有寫進程,則進行等待,一直等到寫鎖釋放後在進行讀。
OSI七層模型:
7:應用層
6:表示層
5:會話層
4:傳輸層
3:網路層
2:數據鏈路層
1:物理層
網際網協議族:
應用層 :OSI的567
TCP |UDP :OSI的4 網路層可直接繞或傳輸層直接使用IPV4或IPV6
IPV4、IPV6 :OSI的3
設備驅動程式和硬體 :OSI的12
UDP:簡單的、不可靠的數據報協議。非連接的協議,傳輸數據之前源端和終端不建立連接,當它想傳據的速度僅僅是受送時就簡單地去抓取來自應用程式的數據,並儘可能快地把它扔到網路上。在發送端,UDP傳送數應用程式生成數據的速度、電腦的能力和傳輸帶寬的限制;在接收端,UDP把每個消息段放在隊列中,應用程式每次從隊列中讀一個消息段。
TCP:複雜的可靠地位元組流協議。是面向連接的協議,也就是說,在收發數據前,必須和對方建立可靠的連接。三次握手四次揮手
三次握手
1)第一次握手:建立連接時,客戶端A發送SYN包(SYN=j)到伺服器B,併進入SYN_SEND狀態,等待伺服器B確認。
(2)第二次握手:伺服器B收到SYN包,必須確認客戶A的SYN(ACK=j+1),同時自己也發送一個SYN包(SYN=k),即SYN+ACK包,此時伺服器B進入SYN_RECV狀態。
(3)第三次握手:客戶端A收到伺服器B的SYN+ACK包,向伺服器B發送確認包ACK(ACK=k+1),此包發送完畢,客戶端A和伺服器B進入ESTABLISHED狀態,完成三次握手。
完成三次握手,客戶端與伺服器開始傳送數據。
四次揮手
(1)客戶端A發送一個FIN,用來關閉客戶A到伺服器B的數據傳送。
(2)伺服器B收到這個FIN,它發回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將占用一個序號。
(3)伺服器B關閉與客戶端A的連接,發送一個FIN給客戶端A。
(4)客戶端A發回ACK報文確認,並將確認序號設置為收到序號加1。
小結TCP與UDP的區別:
1.基於連接與無連接;
2.對系統資源的要求(TCP較多,UDP少);
3.UDP程式結構較簡單;
4.流模式與數據報模式 ;
5.TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證。
SCTP:流控制傳輸協議,可靠地
進程間的幾種通信方式:
# 管道( pipe ):管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
# 有名管道 (named pipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。
# 信號 ( sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
# 信號量( semophore ) : 信號量是一個計數器,可以用來控制多個進程對共用資源的訪問。它常作為一種鎖機制,防止某進程正在訪問共用資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段。
# 消息隊列( message queue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列剋服了信號傳遞信息少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。
# 共用記憶體( shared memory ) :共用記憶體就是映射一段能被其他進程所訪問的記憶體,這段共用記憶體由一個進程創建,但多個進程都可以訪問。共用記憶體是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
# 套接字( socket ) : 套解字也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同機器間的進程通信。
LINUX基本命令:
ls 顯示文件 -l 詳細信息
-a 所有文件,包括隱藏
mkdir 創建目錄
cd 切換目錄
touch 創建空文件
echo 創建帶有內容的文件
cat 查看文件內容
cp 拷貝 (源文件 目的文件)
mv 移動或重命名
rm 刪除文件
-r 可刪除子目錄及文件
-f 強制刪除
rmdir 刪除空目錄
find 在文件系統搜索某文件
wc 統計文本中行數、字數、字元數
grep 在文本文件中查找某字元串
pwd 顯示當前目錄
ln 創建鏈接文件
系統管理命令
stat 顯示指定文件的詳細信息 比ls更詳細
ps 顯示瞬間進程狀態
ifconfig 查看網路情況
ping 測試網路聯通
clear 清屏
kill 殺死進程
chown 更改所有者或用戶組
chmod 更改文件許可權 讀寫執行