📅  最后修改于: 2023-12-03 15:05:45.900000             🧑  作者: Mango
Unix套接字是一种通信机制,用于进程间的通信。Unix套接字是基于文件描述符的,因此可以在一个进程中同时处理多个套接字。通过Unix套接字,我们可以实现本地进程之间的通信,也可以实现网络进程之间的通信。
在Unix系统上,我们可以通过套接字来实现一个简单的服务器。下面是一个使用Unix套接字实现的服务器示例。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "/tmp/sock_path"
int main()
{
int s, s2, t, len;
struct sockaddr_un remote, server;
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket error: %s\n", strerror(errno));
exit(1);
}
printf("Trying to bind to %s\n", SOCK_PATH);
server.sun_family = AF_UNIX;
strcpy(server.sun_path, SOCK_PATH);
unlink(server.sun_path);
len = strlen(server.sun_path) + sizeof(server.sun_family);
if (bind(s, (struct sockaddr *)&server, len) == -1) {
fprintf(stderr, "bind error: %s\n", strerror(errno));
exit(1);
}
if (listen(s, 5) == -1) {
fprintf(stderr, "listen error: %s\n", strerror(errno));
exit(1);
}
while(1) {
int done, n;
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, (socklen_t *)&t)) == -1) {
fprintf(stderr, "accept error: %s\n", strerror(errno));
exit(1);
}
printf("Connection accepted.\n");
do {
n = recv(s2, buf, sizeof(buf), 0);
if (n <= 0) {
if (n < 0) {
fprintf(stderr, "recv error: %s\n", strerror(errno));
}
done = 1;
}
if (!done) {
if (send(s2, buf, n, 0) < 0) {
fprintf(stderr, "send error: %s\n", strerror(errno));
done = 1;
}
}
} while (!done);
close(s2);
}
return 0;
}
创建一个Unix域套接字,返回文件描述符。
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "socket error: %s\n", strerror(errno));
exit(1);
}
将服务器套接字与一个地址绑定,以便客户端可以找到它。
if (bind(s, (struct sockaddr *)&server, len) == -1) {
fprintf(stderr, "bind error: %s\n", strerror(errno));
exit(1);
}
将套接字设置为监听状态,以便客户端可以连接它。
if (listen(s, 5) == -1) {
fprintf(stderr, "listen error: %s\n", strerror(errno));
exit(1);
}
等待客户端的连接请求,接受客户端的连接请求,返回新的文件描述符。
if ((s2 = accept(s, (struct sockaddr *)&remote, (socklen_t *)&t)) == -1) {
fprintf(stderr, "accept error: %s\n", strerror(errno));
exit(1);
}
从客户端接收数据,向客户端发送数据。
do {
n = recv(s2, buf, sizeof(buf), 0);
if (n <= 0) {
if (n < 0) {
fprintf(stderr, "recv error: %s\n", strerror(errno));
}
done = 1;
}
if (!done) {
if (send(s2, buf, n, 0) < 0) {
fprintf(stderr, "send error: %s\n", strerror(errno));
done = 1;
}
}
} while (!done);
编译服务器程序:
$ gcc server.c -o server
在终端窗口1中运行服务器程序:
$ ./server
Trying to bind to /tmp/sock_path
Waiting for a connection...
在终端窗口2中运行客户端程序:
$ gcc client.c -o client
$ ./client
Connected.
在终端窗口1中可以看到服务器程序输出了:
Connection accepted.
这说明客户端已经成功地连接到了服务器端。在终端窗口2中输入一些文字,可以看到回显。这表明客户端已经成功地向服务器发送了数据,服务器也成功地回显了这些数据。