socket起源於unix,而unix/linux基本哲學之一就是「一切皆檔案」,都可以用「開啟open –> 讀寫write/read –> 關閉close」模式來操作。socket就是該模式的乙個實現, socket即是一種特殊的檔案,一些socket函式就是對其進行的操作(讀/寫io、開啟、關閉).
說白了socket是應用層與tcp/ip協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,socket其實就是乙個門面模式,它把複雜的tcp/ip協議族隱藏在socket介面後面,對使用者來說,一組簡單的介面就是全部,讓socket去組織資料,以符合指定的協議。
注意:其實socket也沒有層的概念,它只是乙個facade設計模式的應用,讓程式設計變的更簡單。是乙個軟體抽象層。在網路程式設計中,我們大量用的都是通過socket實現的。
使用套接字除了可以實現網路間不同主機間的通訊外,還可以實現同一主機的不同程序間的通訊,且建立的通訊是雙向的通訊。socket程序通訊與網路通訊使用的是統一套介面,只是位址結構與某些引數不同。
其主要流程如下:
一. 建立socket
建立socket,型別為af_local或af_unix,表示用於程序通訊:
呼叫函式socket(),其原型如下:
int socket(int domain, int type, int protocol);
引數:domain:指定協議族,對於本地套接字來說,值必須設定為af_unix列舉值;
type:指定套接字型別,可以被設定為sock_stream(流式套接字)活sock_dgram(資料報式套接字)
protocol:指定具體的協議,應被設定為0
返回值為生成的套接字描述符。
對於本地套接字來說,流式套接字(sock_stream)是乙個有順序的、可靠的雙向位元組流,相當於在本地程序之間建立起一條資料通道;資料報式套接字(sock_dgram)相當於單純的傳送訊息,在程序通訊過程中,理論上可能會有資訊丟失、複製或者不按先後次序到達的情況,但由於其在本地通訊,不通過外界網路,這些情況出現的概率很小。
二. 設定socket引數
sock_stream式本地套接字的通訊雙方均需要有本地位址,其中伺服器端的本地位址需要明確指定,指定方法是使用struct sockaddr_un型別的變數
struct sockaddr_un
// 設定伺服器引數
srv_addr.sun_family=af_unix;
strncpy(srv_addr.sun_path,can_service,
sizeof(srv_addr.sun_path)
-1);
unlink(can_service);
// 繫結socket位址
ret=bind(socket_fd,(struct sockaddr*)&srv_addr,
sizeof(srv_addr));
if(ret==
-1)
// 監聽
ret=listen(socket_fd,
1);
if(ret==
-1)
// 接受connect請求
len=
sizeof(clt_addr);
accept_fd=accept(socket_fd,(struct sockaddr*)&clt_addr,&len);
if(accept_fd<
0)
// 讀取和寫入
memset(recv_buf,
0,1024);
int num=read(accept_fd,recv_buf,
sizeof(recv_buf));
printf(
"message from client (%d)) :%s\n",num,recv_buf);
// 關閉socket
close(accept_fd);
close(socket_fd);
unlink(can_service);
return
0;
} 2. 客戶端
與本地套接字相對應的是網路套接字,可以用於在網路上傳送資料,換言之,可實現不同機器上的程序通訊過程。在 tcp/ip 協議中,ip 位址的首位元組為 127 即代表本地,因此本地套接字通訊可以使用 ip 位址為 127.x.x.x 的網路套接字來實現。#include
#include
#include
#include
#define can_service "can_service"
intmain
(void)
srv_addr.sun_family=af_unix;
strcpy(srv_addr.sun_path,can_service);
// 連線到伺服器
ret=connect(socket_fd,(struct sockaddr*)&srv_addr,
sizeof(srv_addr));
if(ret==
-1)
memset(snd_buf,
0,1024);
strcpy(snd_buf,
"message from client");
// 讀取和寫入
write(socket_fd,snd_buf,
sizeof(snd_buf));
close(socket_fd);
return
0;
}
socket起源於unix,而unix/linux基本哲學之一就是「一切皆檔案」,都可以用「開啟open –> 讀寫write/read –> 關閉close」模式來操作。socket就是該模式的乙個實現, socket即是一種特殊的檔案,一些socket函式就是對其進行的操作(讀/寫io、開啟、關閉).
Linux下 使用C語言編寫who命令
在linux 下 who命令是查詢當前登入的每個使用者。who的預設輸出包括使用者名稱 終端型別 登入日期及遠端主機。如圖 我們man一下who,在聯機幫助裡可以看到,who命令是讀取 var run utmp檔案來得到以上資訊的。我們在man一下utmp,知道utmp這個檔案,是二進位制檔案,裡面...
linux下c語言程式設計exec函式使用
exec用被執行的程式完全替換呼叫它的程式的影像。fork建立乙個新的程序就產生了乙個新的pid,exec啟動乙個新程式,替換原有的程序,因此這個新的被exec執行的程序的pid不會改變,和呼叫exec函式的程序一樣。下面來看下exec函式族 include std.h int execl cons...
Linux下C語言使用openssl庫進行加密
在這裡插一小節加密的吧,使用openssl庫進行加密。使用md5加密 我們以乙個字串為例,新建乙個檔案filename.txt,在檔案內寫入hello 然後在linux下可以使用命令md5sum filename.txt計算md5值 b1946ac92492d2347c6235b4d2611184 ...