在這篇文章中筆者將以socket應(yīng)用為重點, 跟大家分享一下socket的應(yīng)用. 我們都知道socket是通信套接字, 其實socket的應(yīng)用不僅可以用在網(wǎng)絡(luò)通信中, 本地進(jìn)程通信也可以使用socket來實現(xiàn).
什么是基于socket的IPC
IPC 通信有多種實現(xiàn)方式, 從大的類別上可以分為基于文件的IPC 和 基于內(nèi)存的IPC. 基于文件的IPC又分為基于有序文件和基于無序文件. 基于有序文件的實現(xiàn)方式又分為管道和socket. 本文主要說的就是基于socket有序文件的IPC.
通過對等模型建立socket的IPC
建立socket, 在內(nèi)存中開辟一塊空間, 返回一個文件描述符號.這塊內(nèi)存空間可以指向本地文件或者網(wǎng)卡設(shè)備(這個取決于綁定的地址, 地址唯一決定了一個物理設(shè)備). 如果是本地文件, 系統(tǒng)會自動創(chuàng)建一個socket文件. 如果是網(wǎng)卡, socket開辟的這片內(nèi)存空間指向的就是一個ip地址.
向socket開辟的內(nèi)存中寫數(shù)據(jù),如果bind的是本地文件, 內(nèi)存中的數(shù)據(jù)就會記錄到本地socket文件中, 如果bind的地址是網(wǎng)卡, 內(nèi)存中的數(shù)據(jù)就會發(fā)送給網(wǎng)卡.
接收端進(jìn)程
int fd = socket(AF_UNIX,SOCK_DGRAM,0);
if(fd == -1){
printf("socket error: %m \n");
exit(-1);
}
printf("socket success! \n");
//2, 構(gòu)造本地文件地址
struct sockaddr_un addr = {0};
addr.sun_family = AF_UNIX;
memcpy(addr.sun_path,"IPC.sock", strlen("IPC.sock"));
//3, 把socket綁定在地址上
r = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
if(r == -1) {
printf("bind error: %m \n");
close(fd);
exit(-1);
}
printf("bind success ! \n");
//4, 接收數(shù)據(jù)
char buf[200];
while(1){
bzero(buf, sizeof(buf));
r = read(fd, buf, sizeof(buf));// 從fd中讀取數(shù)據(jù)放入buf中, 讀取的長度是sizeof(buf)
buf[r] = 0;
printf("%s\n", buf);
}
//5, 關(guān)閉
close(fd);
//6, 刪除socket 文件
unlink("IPC.sock");
發(fā)送端進(jìn)程
int fd;
int r;
struct sockaddr_un addr = {0};
//1, ??socket??
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
//2, ????????????????????????連接
addr.sun_family = AF_UNIX;
memcpy(addr.sun_path, "IPC.sock", strlen("IPC.sock"));
r = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
//3, ????????????發(fā)送數(shù)據(jù)
write(fd, "hello! Alice!", strlen("hello! Alice!"));
//4, ????關(guān)閉網(wǎng)絡(luò)
close(fd);