1 本地套接字
1.1 注意事项
- 创建Socket套接字时传递的参数与网络套接字不同,域参数应该是AF_LOCAL或者AF_UNIX,而不能用AF_INET之类。
- 不同于网络套接字的绑定,本地套接字绑定的是struct sockaddr_un结构。
- 客户端在连接前同样需要绑定本地套接字,并且填充服务端sockaddr_un地址结构,然后再进行connect。
- 在通信结束后,需要删除套接字文件后才能再次运行,可使用unlink()函数在程序运行开始时删除相应文件。
1.2 sockaddr_un结构体
#include <sys/un.h>
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[UNIX_PATH_MAX];
};
2 程序示例
2.1 服务端程序
#include <iostream>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <string.h>
#define MAX_CONN 1024
using namespace std;
int main() {
int lfd, cfd;
sockaddr_un addr, caddr;
socklen_t len =sizeof(caddr);
unlink("server.sock");
if((lfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(-1);
}
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "server.sock");
if(bind(lfd, (sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind");
exit(-1);
}
listen(lfd, MAX_CONN);
if((cfd = accept(lfd, (sockaddr *)&caddr, &len)) == -1) {
perror("accept");
exit(-1);
}
while(1) {
char buf[1024];
int len = recv(cfd, buf, sizeof(buf), 0);
if(len == -1) {
perror("recv");
exit(-1);
}
else if(len == 0) {
cout << "(SERVER) client closed..." << endl;
break;
}
else if(len > 0) {
cout << "(SERVER) recv : " << buf << endl;
send(cfd, buf, len ,0);
}
}
close(cfd);
close(lfd);
return 0;
}
2.2 客户端程序
#include <iostream>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <string.h>
#define MAX_CONN 1024
using namespace std;
int main() {
int cfd;
sockaddr_un addr, saddr;
unlink("client.sock");
if((cfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(-1);
}
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "client.sock");
if(bind(cfd, (sockaddr *)&addr, sizeof(addr)) == -1) {
perror("bind");
exit(-1);
}
saddr.sun_family = AF_LOCAL;
strcpy(saddr.sun_path, "server.sock");
if(connect(cfd, (sockaddr *)&saddr, sizeof(saddr)) == -1) {
perror("connect");
exit(-1);
}
int num = 0;
while(1) {
char buf[1024];
sprintf(buf, "i am client : %d\n", num++);
send(cfd, buf, strlen(buf) + 1, 0);
int len = recv(cfd, buf, sizeof(buf), 0);
if(len == -1) {
perror("recv");
exit(-1);
}
else if(len == 0) {
cout << "(CLIENT) server closed..." << endl;
break;
}
else if(len > 0) {
cout << "(CLIENT) recv : " << buf << endl;
}
sleep(1);
}
close(cfd);
return 0;
}
2.3 运行结果