轉(zhuǎn)載請標(biāo)明出處:http://www.reibang.com/users/183339cdc7ae/latest_articles
概述
socket通信是大家耳熟能詳?shù)囊环N進程間通信方式(IPC)尽纽,它是一種全雙工的通信方式启盛,不同于pipe這種單工方式.這篇文章將深入淺出的講解一下什么是socket矿咕。
我們常說的socket通信有以下二種,主要會說一下Unix domain socket
Internet domain socket
該socket可以用于不同主機間的通信名挥,就像聊QQ一樣只要知道了對方的QQ號就可以聊天了。socket只要知道了對方的ip地址和端口就可以通信了所以這種socket通信是基于網(wǎng)絡(luò)協(xié)議棧的县好。
Unix domain socket
該socket用于一臺主機的進程間通信围橡,不需要基于網(wǎng)絡(luò)協(xié)議,主要是基于文件系統(tǒng)的聘惦。與Internet domain socket類似某饰,需要知道是基于哪一個文件(相同的文件路徑)來通信的
unix domain socket有2種工作模式一種是SOCK_STREAM儒恋,類似于TCP,可靠的字節(jié)流黔漂。另一種是SOCK_DGRAM诫尽,類似于UDP,不可靠的字節(jié)流炬守。
工作模型
socket通信有一個服務(wù)端牧嫉,一個客服端
服務(wù)端:創(chuàng)建socket—綁定文件(端口)—監(jiān)聽—接受客戶端連接—接收/發(fā)送數(shù)據(jù)—…—關(guān)閉
客戶端:創(chuàng)建socket—綁定文件(端口)—連接—發(fā)送/接收數(shù)據(jù)—…—關(guān)閉
代碼框架
server
sockaddr_un :為一個系統(tǒng)級的結(jié)構(gòu)體,主要用于存儲地址
#define NAME "socketAddr"
main(){
...
struct sockaddr_un server;
...
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
strcpy (server.sun_path, NAME);
...
bind(sock, (structsockaddr *) &server, sizeof(struct sockaddr_un));
...
listen(sock, 5);
...
while(1){
...
msgsock = accept(sock, 0, 0);
...
rval = read(msgsock, buf, 1024))
...
}
}
client
#define NAME "socketAddr"
main(){
...
sock = socket(AF_UNIX, SOCK_STREAM, 0);
strcpy(server.sun_path, NAME);
...
if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
close(sock);
exit(1);
}
if (write(sock, DATA, sizeof(DATA)) < 0)
perror("writing on stream socket");
close(sock);
}
demo下載
github下載
使用:
- gcc service.c -o service
- gcc client.c -o client
- linux下啟動一個窗口運行 ./service
- 啟動另一個窗口運行 ./client socket 【這個socket為service中綁定的地址】
運行后可以發(fā)現(xiàn)减途,在當(dāng)前目錄下會多一個名叫socket的文件酣藻,這2個進程就是基于該文件通信的