现在的位置: 首页 > 综合 > 正文

socket IPC(转)

2013年09月03日 ⁄ 综合 ⁄ 共 2536字 ⁄ 字号 评论关闭

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;
}

抱歉!评论已关闭.