int ser_afinet_listen(int port)
{
int listenfd, on;
struct sockaddr_in seraddr;
listenfd = socket(af_inet, sock_stream, 0);
if (listenfd < 0) {
fprintf(stderr, "socket: %s\n", strerror(errno));
return -1;
}
on = 1;
setsockopt(listenfd, sol_socket, so_reuseaddr, &on, sizeof(on));
seraddr.sin_family = af_inet;
seraddr.sin_port = port;
seraddr.sin_addr.s_addr = htonl(inaddr_any);
if (bind(listenfd, (struct sockaddr *)&seraddr, sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr, "bind: %s\n", strerror(errno));
return -1;
}
if (listen(listenfd, sock_ipc_max_conn) < 0) {
fprintf(stderr, "listen: %s\n", strerror(errno));
return -1;
}
return listenfd;
}int ser_accept(int listenfd)
{
int connfd;
struct sockaddr_un cltaddr;
ssize_t recvlen, sendlen;
char buf[sock_ipc_max_buf];
socklen_t addrlen;
addrlen = sizeof(cltaddr);
for (;;) {
connfd = accept(listenfd, (struct sockaddr *)&cltaddr, &addrlen);
if (connfd < 0) {
fprintf(stderr, "accept: %s\n", strerror(errno));
return -1;
}
if (recvlen = ipc_recv(connfd, buf, sizeof(buf)) < 0) {
continue;
}
printf("recv: %s\n", buf);
snprintf(buf, sizeof(buf), "hello, ipc client!");
if (ipc_send(connfd, buf, strlen(buf)) < 0) {
continue;
}
close(connfd);
}
}
客户进程初始化如下:int clt_afinet_conn_init(int port)
{
int fd;
fd = socket(af_inet, sock_stream, 0);
if (fd < 0) {
fprintf(stderr, "socket: %s\n", strerror(errno));
return -1;
}
seraddr.sin_family = af_inet;
seraddr.sin_port = port;
if (inet_pton(af_inet, "127.0.0.1", &seraddr.sin_addr) < 0) {//环回地址
fprintf(stderr, "inet_pton: %s\n", strerror(errno));
return -1;
}
return fd;
}if (connect(fd, (struct sockaddr *)&seraddr, sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr, "connect: %s\n", strerror(errno));
return -1;
}
if ((sendlen = ipc_send(fd, buf, strlen(buf))) < 0) {
return -1;
}
if ((recvlen = ipc_recv(fd, buf, sizeof(buf))) < 0) {
return -1;
}
#include<sys/socket.h> int socket(int domain, int type, int protocol);其中,domain 参数指定协议族,对于本地套接字来说,其值被置为 af_unix 枚举值,随便说一下,af_unix和af_local是同一个值,看下面linux/socket.h头文件部分如下,两个宏的值都一样为1。
…… /* supported address families. */ #define af_unspec 0 #define af_unix 1 /* unix domain sockets */ #define af_local 1 /* posix name for af_unix */ #define af_inet 2 /* internet ip protocol */ #define af_ax25 3 /* amateur radio ax.25 */ ……以af_xx开头和pf_xx开头的域都是一样的,继续看头文件部分内容就一切都明白了:
…… #define pf_unspec af_unspec #define pf_unix af_unix #define pf_local af_local #define pf_inet af_inet #define pf_ax25 af_ax25 ……所以我们在指定socket的类型时这四个域可以随便用啦,笔者这里统一使用af_unix了。
#ifndef _linux_un_h
#define _linux_un_h
#define unix_path_max 108
struct sockaddr_un {
sa_family_t sun_family; /* af_unix */
char sun_path[unix_path_max]; /* pathname */
};
#endif /* _linux_un_h */创建监听套接字:int ser_afunix_listen(const char *pathname)
{
int listenfd, on;
struct sockaddr_un seraddr;
listenfd = socket(af_unix, sock_stream, 0);
if (listenfd < 0) {
fprintf(stderr, "socket: %s\n", strerror(errno));
return -1;
}
unlink(pathname);
seraddr.sun_family = af_unix;
snprintf(seraddr.sun_path, sizeof(seraddr.sun_path), "%s", pathname);
if (bind(listenfd, (struct sockaddr *)&seraddr, sizeof(struct sockaddr_un)) < 0) {
fprintf(stderr, "bind: %s\n", strerror(errno));
return -1;
}
if (listen(listenfd, sock_ipc_max_conn) < 0) {
fprintf(stderr, "listen: %s\n", strerror(errno));
return -1;
}
return listenfd;
}服务进程处理连接请求类似上面网络通信。int clt_afunix_conn_init(const char *pathname)
{
int fd;
struct sockaddr_un localaddr;
fd = socket(af_unix, sock_stream, 0);
if (fd < 0) {
fprintf(stderr, "socket: %s\n", strerror(errno));
return -1;
}
localaddr.sun_family = af_unix;
snprintf(localaddr.sun_path, sizeof(localaddr.sun_path), "%s-cltid%d", pathname, getpid());
if (bind(fd, (struct sockaddr *)&localaddr, sizeof(struct sockaddr_un)) < 0) {
fprintf(stderr, "bind: %s\n", strerror(errno));
return -1;
}
seraddr.sun_family = af_unix;
snprintf(seraddr.sun_path, sizeof(seraddr.sun_path), "%s", pathname);
return fd;
}细说linux IPC(一):基于socket的进程间通信(上)
原文:http://blog.csdn.net/shallnet/article/details/40977165