server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/epoll.h>
#define SOCKET_PATH "/tmp/mysocket.sock"
#define MAX_EVENTS 10
#define BUFFER_SIZE 256
void handle_client(int client_socket) {
char buffer[BUFFER_SIZE];
ssize_t bytes_read = read(client_socket, buffer, sizeof(buffer) - 1);
if (bytes_read > 0) {
buffer[bytes_read] = '\0'; // null-terminate the string
printf("Received: %s\n", buffer);
}
close(client_socket);
}
int main() {
int server_socket, client_socket, epoll_fd;
struct sockaddr_un addr;
struct epoll_event event, events[MAX_EVENTS];
// 创建 UNIX 域套接字
server_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
// 设置套接字地址
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
// 绑定套接字
unlink(SOCKET_PATH); // 移除已有的套接字文件(如果存在)
if (bind(server_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind error");
close(server_socket);
exit(EXIT_FAILURE);
}
// 开始监听客户端连接
if (listen(server_socket, SOMAXCONN) < 0) {
perror("listen error");
close(server_socket);
exit(EXIT_FAILURE);
}
// 创建 epoll 实例
epoll_fd = epoll_create1(0);
if (epoll_fd < 0) {
perror("epoll_create1 error");
close(server_socket);
exit(EXIT_FAILURE);
}
// 将服务器套接字添加到 epoll 实例中
event.events = EPOLLIN;
event.data.fd = server_socket;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &event) < 0) {
perror("epoll_ctl error");
close(epoll_fd);
close(server_socket);
exit(EXIT_FAILURE);
}
printf("Server is running, waiting for connections...\n");
while (1) {
int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < n; i++) {
if (events[i].data.fd == server_socket) {
// 接收新的客户端连接
client_socket = accept(server_socket, NULL, NULL);
if (client_socket < 0) {
perror("accept error");
continue;
}
// 将客户端套接字添加到 epoll 中
event.events = EPOLLIN;
event.data.fd = client_socket;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_socket, &event) < 0) {
perror("epoll_ctl for client error");
close(client_socket);
}
} else {
// 处理客户端消息
handle_client(events[i].data.fd);
}
}
}
close(epoll_fd);
close(server_socket);
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCKET_PATH "/tmp/mysocket.sock"
#define MESSAGE "Hello, Server!"
int main() {
int client_socket;
struct sockaddr_un addr;
// 创建 UNIX 域套接字
client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (client_socket < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
// 设置套接字地址
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
// 连接到服务器
if (connect(client_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect error");
close(client_socket);
exit(EXIT_FAILURE);
}
// 发送消息
if (send(client_socket, MESSAGE, strlen(MESSAGE), 0) < 0) {
perror("send error");
}
// 关闭客户端套接字
close(client_socket);
return 0;
}
编译运行
# 编译服务器端和客户端
gcc -o server server.c
gcc -o client client.c
# 先运行服务器
./server &
# 然后运行客户端
./client
记录用