LINUX本地socket通讯AF_UNIX地址族,服务端客户端通讯demo
AF_UNIX适用于本机进程间通讯,效率高,支持流SOCK_STREAM和数据报SOCK_DGRAM,其实都是面向可靠的链接
server端代码
#include <pthread.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/epoll.h>
void SetNoBlock(int fd)
{
int option = fcntl(fd, F_GETFD);
if (option < 0) {
return;
}
option = option | O_NONBLOCK | FD_CLOEXEC;
option = fcntl(fd, F_SETFD, option);
if (option < 0) {
return;
}
return;
}
static int CreatePipeServerSocket_(const char *server, int maxClient)
{
int listenfd = socket(PF_UNIX, SOCK_STREAM, 0);
unlink(server);
struct sockaddr_un serverAddr;
int ret = 0;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_UNIX;
strcpy(serverAddr.sun_path, server);
uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(server);
ret = bind(listenfd, (struct sockaddr *)&serverAddr, size);
SetNoBlock(listenfd);
ret = listen(listenfd, maxClient);
if (ret < 0) {
printf("error");
}
printf("CreatePipeSocket listen fd: %d server:%s \n", listenfd, serverAddr.sun_path);
return listenfd;
}
static int CreatePipeSocket_(const char *server)
{
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
SetNoBlock(fd);
struct sockaddr_un serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_UNIX;
strcpy(serverAddr.sun_path, server);
uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
int ret = connect(fd, (struct sockaddr *)&serverAddr, size);
printf("CreatePipeSocket connect fd: %d server: %s \n", fd, serverAddr.sun_path);
return fd;
}
static int AcceptPipeSocket_(int serverFd)
{
struct sockaddr_un clientAddr;
socklen_t addrlen = sizeof(clientAddr);
bzero(&clientAddr, addrlen);
int fd = accept(serverFd, (struct sockaddr *)&clientAddr, &addrlen);
printf("AcceptPipeSocket client fd %d %s \n", fd, clientAddr.sun_path);
return fd;
}
void RunServer()
{
int maxevents = 5;
int epollFd = 0;
epollFd = epoll_create(maxevents);
if (epollFd == 0) {
printf("error epollFd is 0\n");
}
if(access("/home/cc/test_socket",F_OK))
{
unlink("/home/cc/test_socket");//删除该文件
}
int lfd = CreatePipeServerSocket_("/home/cc/test_socket", 10);
struct epoll_event event = {};
event.events = EPOLLIN;
//绑定事件fd
event.data.fd = lfd;
if (lfd < 0) {
printf("create pipe failed\n");
}
int ret = epoll_ctl(epollFd, EPOLL_CTL_ADD, lfd, &event);
if (ret < 0) {
printf("epoll_ctl failed\n");
}
struct epoll_event waitEvents[5] = {};
while (1) {
int number = epoll_wait(epollFd, waitEvents, 5, -1);
for (int index = 0; index < number; index++) {
if (waitEvents[index].events & EPOLLIN == EPOLLIN && waitEvents[index].data.fd == lfd) {
int confd = AcceptPipeSocket_(lfd);
struct epoll_event event = {};
event.events = EPOLLIN;
event.data.fd = confd;
epoll_ctl(epollFd, EPOLL_CTL_ADD, confd, &event);
continue;
}
if (waitEvents[index].events & EPOLLIN == EPOLLIN) {
int rfd = waitEvents[index].data.fd;
char buff[1024];
recv(rfd, buff, 1024, 0);
send(rfd, "hello", 6, 0);
}
}
}
}
int main()
{
RunServer();
return 0;
}
客户端代码
#include <pthread.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/epoll.h>
void SetNoBlock(int fd)
{
int option = fcntl(fd, F_GETFD);
if (option < 0) {
return;
}
option = option | O_NONBLOCK | FD_CLOEXEC;
option = fcntl(fd, F_SETFD, option);
if (option < 0) {
return;
}
return;
}
static int CreatePipeSocket_(const char *server)
{
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
SetNoBlock(fd);
struct sockaddr_un serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sun_family = AF_UNIX;
strcpy(serverAddr.sun_path, server);
uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
int ret = connect(fd, (struct sockaddr *)&serverAddr, size);
if (ret != 0) {
printf("connect failed\n");
}
printf("CreatePipeSocket connect fd: %d server: %s\n", fd, serverAddr.sun_path);
return fd;
}
int main()
{
int confd = CreatePipeSocket_("/home/cc/test_socket");
char buf[1024];
while (1)
{
sleep(1);
printf("n\n");
send(confd, "hello", 6, MSG_DONTWAIT);
recv(confd, buf, 1024, 0);
printf("%s\n",buf);
buf[0] = 0;
}
return 0;
}
本文提供了一个LINUX环境下使用AF_UNIX进行本地socket通讯的服务端与客户端示例代码。通过使用流SOCK_STREAM实现可靠的数据传输,示例展示了如何创建、连接及接受socket,并利用epoll进行事件监听。

被折叠的 条评论
为什么被折叠?



