1.流式域套接字服务器端实现
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
int main() {
int oldfd;
// 创建 socket
if ((oldfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
return -1;
}
// 判断文件是否存在,存在就删除
if (access("./myclient", F_OK) == 0) {
if (unlink("./myclient") == -1) {
perror("unlink");
return -1;
}
}
// 设置客户端套接字地址
struct sockaddr_un client;
client.sun_family = AF_UNIX;
strcpy(client.sun_path, "./myclient");
// 绑定客户端套接字(可选)
if (bind(oldfd, (struct sockaddr *)&client, sizeof(client)) == -1) {
perror("bind");
return -1;
}
// 设置服务器套接字地址
struct sockaddr_un server;
server.sun_family = AF_UNIX;
strcpy(server.sun_path, "./myserver");
// 连接服务器
if (connect(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
perror("connect");
return -1;
}
printf("连接服务器成功\n");
char buff[1024];
while (1) {
// 清空缓冲区
bzero(buff, sizeof(buff));
// 获取用户输入
printf("请输入要发送的信息: ");
fgets(buff, sizeof(buff), stdin);
// 去掉换行符
buff[strlen(buff) - 1] = '\0';
// 发送信息
if (send(oldfd, buff, strlen(buff), 0) == -1) {
perror("send");
return -1;
}
printf("发送成功\n");
// 如果输入 quit,退出循环
if (strcmp(buff, "quit") == 0)
break;
// 接收服务器信息
if (recv(oldfd, buff, sizeof(buff), 0) == -1) {
perror("recv");
return -1;
}
printf("接收服务器的信息: %s\n", buff);
}
// 关闭 socket
close(oldfd);
return 0;
}
2、报式域套接字服务器端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
int main() {
int oldfd;
// 创建 socket
if ((oldfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { // 使用 SOCK_DGRAM,因为它更适合 recvfrom/sendto 的无连接方式
perror("socket");
return -1;
}
// 判断文件是否存在,存在就删除
if (access("./myserver", F_OK) == 0) {
if (unlink("./myserver") == -1) {
perror("unlink");
return -1;
}
}
// 设置服务器套接字地址
struct sockaddr_un server;
server.sun_family = AF_UNIX;
strcpy(server.sun_path, "./myserver");
// 绑定服务器地址
if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
perror("bind");
return -1;
}
// 进入消息收发循环
struct sockaddr_un client; // 定义客户端信息结构体
socklen_t clientlen = sizeof(client);
char buff[1024];
while (1) {
// 清空缓冲区
bzero(buff, sizeof(buff));
// 接收客户端消息
if (recvfrom(oldfd, buff, sizeof(buff), 0, (struct sockaddr *)&client, &clientlen) == -1) {
perror("recvfrom");
return -1;
}
printf("接收到 %s 的消息\n", client.sun_path);
printf("收到客户端信息: %s\n", buff);
// 添加标识符后再发送回客户端
strcat(buff, "*_*");
// 发送消息回客户端
if (sendto(oldfd, buff, strlen(buff), 0, (struct sockaddr *)&client, clientlen) == -1) {
perror("sendto");
return -1;
}
printf("转发成功\n");
}
// 关闭文件描述符
close(oldfd);
return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
int main() {
// 1、创建报式域套接字
int oldfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (oldfd == -1) {
perror("socket");
return -1;
}
// 2、判断文件是否存在,存在就删除
if (access("./myclient", F_OK) == 0) {
if (unlink("./myclient") == -1) {
perror("unlink");
return -1;
}
}
// 3、绑定客户端套接字
struct sockaddr_un client; // 定义客户端信息结构体
client.sun_family = AF_UNIX;
strcpy(client.sun_path, "./myclient");
if (bind(oldfd, (struct sockaddr *)&client, sizeof(client)) == -1) {
perror("bind");
return -1;
}
// 4、收发消息
struct sockaddr_un server; // 定义服务器端信息结构体
server.sun_family = AF_UNIX;
strcpy(server.sun_path, "./myserver"); // 注意这里填充服务器端的文件
char buff[1024];
while (1) {
// 获取用户输入
printf("请输入要发送的信息: ");
fgets(buff, sizeof(buff), stdin);
// 去掉换行符
buff[strlen(buff) - 1] = '\0';
// 发送消息到服务器
int len = sendto(oldfd, buff, strlen(buff), 0, (struct sockaddr *)&server, sizeof(server));
if (len == -1) {
perror("sendto");
break;
}
// 接收服务器回复的消息
if (recvfrom(oldfd, buff, sizeof(buff), 0, NULL, NULL) == -1) {
perror("recvfrom");
break;
}
printf("服务器发来信息: %s\n", buff);
// 如果发送的信息是 "quit",则退出循环
if (strcmp(buff, "quit") == 0) {
break;
}
}
// 关闭套接字
close(oldfd);
return 0;
}