socket IPC(轉)

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是傳入傳出參數,在傳入時如果沒有指定大小,有可能傳入上次傳出參數值。

    if((csock = accept(ssock,(sockaddr*)un,(socklen_t*)&len)) < 0)
    {
        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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章