在使用socket()函数创建套接字时,当需要在本地进程间进行通信而不涉及网络传输时,可以使用AF_UNIX或AF_LOCAL作为domain参数的取值。AF_UNIX和AF_LOCAL表示使用Unix域套接字(Unix Domain Socket)。
Unix域套接字提供了一种在同一台计算机上进行进程间通信的机制,它不需要通过网络协议栈进行数据传输,而是直接在内核中进行数据交换。使用Unix域套接字进行通信可以获得较高的性能和安全性,并且不受网络相关因素的影响。
Unix域套接字的地址结构使用struct sockaddr_un,在Unix/Linux系统中定义如下:
#include <sys/un.h>
struct sockaddr_un {
sa_family_t sun_family; // AF_UNIX or AF_LOCAL
char sun_path[UNIX_PATH_MAX]; // socket path
};
其中,sun_family字段指定了地址族为AF_UNIX或AF_LOCAL,sun_path字段表示Unix域套接字的路径。
使用Unix域套接字时,可以通过指定文件系统中的一个路径作为套接字的地址,不同进程可以通过该路径来进行通信。常见的应用场景包括在同一台计算机上的进程间通信、服务器进程与其它进程间的通信等。
总结来说,当需要在本地进程间进行通信,不涉及网络传输时,可以使用AF_UNIX或AF_LOCAL作为domain参数的取值,并使用Unix域套接字来实现进程间通信。
以下是一个简单的C语言示例:
进程A
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int sockfd;
struct sockaddr_un addr;
// 创建Unix域套接字
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket creation failed");
return -1;
}
// 设置Unix域套接字地址
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/my_socket", sizeof(addr.sun_path) - 1);
// 连接到Unix域套接字
if (connect(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) == -1) {
perror("connect failed");
close(sockfd);
return -1;
}
// 向服务器发送数据
const char* message = "Hello from Process A";
if (write(sockfd, message, strlen(message)) == -1) {
perror("write failed");
close(sockfd);
return -1;
}
// 关闭套接字
close(sockfd);
return 0;
}
进程B:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int sockfd, newsockfd;
struct sockaddr_un addr;
socklen_t addr_len;
char buffer[1024];
// 创建Unix域套接字
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket creation failed");
return -1;
}
// 设置Unix域套接字地址
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/my_socket", sizeof(addr.sun_path) - 1);
// 绑定Unix域套接字
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) == -1) {
perror("bind failed");
close(sockfd);
return -1;
}
// 监听连接请求
if (listen(sockfd, 5) == -1) {
perror("listen failed");
close(sockfd);
return -1;
}
// 接受客户端连接
addr_len = sizeof(struct sockaddr_un);
newsockfd = accept(sockfd, (struct sockaddr*)&addr, &addr_len);
if (newsockfd == -1) {
perror("accept failed");
close(sockfd);
return -1;
}
// 从客户端接收数据
ssize_t num_bytes = read(newsockfd, buffer, sizeof(buffer) - 1);
if (num_bytes == -1) {
perror("read failed");
close(newsockfd);
close(sockfd);
return -1;
}
buffer[num_bytes] = '\0';
printf("Received message: %s\n", buffer);
// 关闭连接
close(newsockfd);
close(sockfd);
return 0;
}