cpp
#include<stdlib.h>
#include<stdio.h>
#include<stddef.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#define SOCKET_PAHT "unix_domain.socket"
#define SERVER_MODE 1
#define CLIENT_MODE 2
#define BUF_LEN 1024
static struct sockaddr_un socket_addr;
static char *buf;
void handle_error(char *err_msg)
{
perror(err_msg);
unlink(SOCKET_PAHT);
exit(-1);
}
void server_mode(int sockfd)
{
//服务端接收消息 收到EOF表示结束
struct sockaddr_un client_addr;
int client_fd ,msg_len,tmep_result;
//1、绑定
tmep_result = bind(sockfd,(struct sockaddr *)&socket_addr,sizeof(socket_addr));
if (tmep_result < 0)
{
handle_error("bind");
}
//2、挂起监听
tmep_result = listen(sockfd,120);
if (tmep_result < 0)
{
handle_error("listen");
}
//3、获取连接
socklen_t client_len = sizeof(client_addr);
client_fd = accept(sockfd,(struct sockaddr *)&client_addr,&client_len);
if (client_fd < 0)
{
handle_error("accept");
}
printf("接收到客户端的连接\n");
do
{
//接收数据到缓存
memset(buf,0,1024);
//接收数据
msg_len = recv(client_fd,buf,BUF_LEN,0);
if (msg_len < 0)
{
handle_error("recv");
}
if (strncmp(buf,"EOF",3) != 0)
{
printf("接收到客户端信息:%s\n",buf);
strcpy(buf,"OK\n\0");
}
else
{
printf("收到EOF,停止接收数据\n");
}
//回复OK或者EOF
tmep_result = send(client_fd,buf,strlen(buf),0);
if (tmep_result < 0)
{
handle_error("send");
}
} while (strncmp(buf,"EOF",3));
unlink(SOCKET_PAHT);
}
void client_mode(int sockfd)
{
//客户端发送消息 发送EOF表示结束
int temp_result , msg_len;
//连接服务端
temp_result = connect(sockfd,(struct sockaddr*)&socket_addr,sizeof(socket_addr));
if(temp_result < 0)
{
handle_error("connect");
}
do
{
printf("请输入要发送的数据\n");
msg_len = read(STDIN_FILENO,buf,BUF_LEN);
temp_result = send(sockfd,buf,BUF_LEN,0);
if (temp_result < 0)
{
handle_error("send");
}
//清空缓存
memset(buf,0,BUF_LEN);
recv(sockfd,buf,BUF_LEN,0);
printf("接收到服务端回复的消息:%s\n",buf);
} while (strncmp(buf,"EOF",3) != 0);
temp_result = shutdown(sockfd,SHUT_WR);
if (temp_result < 0)
{
handle_error("shutdown");
}
}
int main(int argc, char const *argv[])
{
int mode = 0 , sockfd;
//设计结构
//通过main方法传参的方式 启动不同的客户端和服务端
//如果不填写参数 或者填写参数是server
if (argc == 1 || strncmp(argv[1],"sever",6) == 0)
{
mode = SERVER_MODE;
}
else if(strncmp(argv[1],"client",6) == 0)
{
mode = CLIENT_MODE;
}
else
{
perror("参数错误");
exit(EXIT_FAILURE);
}
//创建socket ipc通讯
//清空
memset(&socket_addr,0,sizeof(socket_addr));
buf = malloc(BUF_LEN);
socket_addr.sun_family=AF_UNIX;
strcpy(socket_addr.sun_path,SOCKET_PAHT);
sockfd = socket(AF_UNIX,SOCK_STREAM,0);
if (sockfd < 0)
{
handle_error("socket");
}
switch (mode)
{
case SERVER_MODE:
server_mode(sockfd);
break;
case CLIENT_MODE:
client_mode(sockfd);
break;
default:
break;
}
close(sockfd);
free(buf);
return 0;
}
makefile
cpp
socket_ipc_test:socket_ipc_test.c
-$(CC) -o $@ $^ -lpthread
