socket IPC與一般網絡通信一致,也有兩種類型sock_stream 和sock_daram不同的地方在於:
1.網絡通信server端以IP/Port作爲服務名,IPC則以socket文件路徑名作爲服務名,socket文件與一般文件不同,socket文件是在程序運行時創建,而不能手動創建。
2.Domain不同,一個是AF_INET,一個是AF_UNIX;使用的地址結構不同,一個是sockaddr_in,一個是sockaddr_un. struct sockaddr_un{int sun_family;char sun_path[108];}
3.客戶端與服務器一樣可以綁定一個文件路徑,綁定之後會生成一個socket文件。此文件並沒有什麼作用,可以直接刪除,通信不會受到影響。
//server端
#include <stdio.h>
#include <stdlib.h>#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <unistd.h>
int bindSocket(char* servname)
{
struct sockaddr_un usock;
int ufd;
memset(&usock,0,sizeof(sockaddr_un));
usock.sun_family = AF_UNIX;
strcpy(usock.sun_path,servname);
if((ufd = socket(AF_UNIX,SOCK_STREAM,0)) < 0)
{
perror("socket() error!");
exit(-1);
}
int len = offsetof(sockaddr_un,sun_path) + strlen(usock.sun_path);
if(bind(ufd,(sockaddr*)&usock,len) < 0)
{
perror("bind() error!");
exit(-1);
}
return ufd;
}
int acceptSocket(int ssock,sockaddr_un *un)
{
int csock,len;
len = sizeof(un); //這句話必須有,因爲len是傳入傳出參數,在傳入時如果沒有指定大小,有可能傳入上次傳出參數值。
{
perror("accept() error!");
exit(-1);
}
len -= offsetof(sockaddr_un,sun_path);
un->sun_path[len] = 0;
printf("client file:%s\n",un->sun_path);
return csock;
}
int main(void)
{
char servName[20];
sprintf(servName,"server");
int sfd = bindSocket(servName);
if(listen(sfd,5) < 0)
{
perror("listen() error!");
exit(-1);
}
struct sockaddr_un un;
int cfd = acceptSocket(sfd,&un);
char buf[100];
int s = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,s);
}
//客戶端
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>
#include <stddef.h>
int cli_connect(const char *name)
{
int len;
struct sockaddr_un un;
memset(&un,0,sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path,"client%05d",getpid());
int cfd;
if((cfd = socket(AF_UNIX,SOCK_STREAM,0)) < 0)
{
perror("socket() error");
exit(-1);
}
len = offsetof(sockaddr_un,sun_path) + strlen(un.sun_path);
if(bind(cfd,(sockaddr*)&un,len) < 0)
{
perror("bind() error");
exit(-1);
}
memset(&un,0,sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path,name);
len = offsetof(sockaddr_un,sun_path);
len += strlen(un.sun_path);
printf("%s\n",un.sun_path);
if(connect(cfd,(sockaddr*)&un,len) < 0)
{
perror("connect() error");
exit(-1);
}
return cfd;
}
int main(void)
{
int cfd = cli_connect("qw/server");
char *buf = "hello world!";
if(write(cfd,buf,strlen(buf)) < 0)
perror("error");
return cfd;
}