UNIX域套接字地址结构
#include <sys/un.h>
struct sockaddr_un {
sa_family sun_family;
char sun_path[104];
}
套接字函数
1、路径最好是绝对路径,不要相对路径;
2、和connect调用中指定的路径名必须是一个当前绑定在某个打开的UNIX域套接字上的路径名,而且他们的套接字类型(字节流或数据报)也必须一致;
3、在一个未绑定的Unix域套接字上发送数据报不会自动给这个套接字捆绑一个路径名,这点不同于UDP套接字(对于UDP套接字,会自动绑定一个临时端口),所以对于数据报UNIX域套接字客户端,则必须调用bind。
UNIX域字节流客户端/服务端
客户端:
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/
#define PATH "/home/unix_sock_xxxxx"
#define MAX_BUF_LEN 255
int main() {
int sockfd = 0;
sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_LOCAL;
strncpy(addr.sun_path, PATH, sizeof(addr.sun_path) - 1);
connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
printf("client is on...\n");
int i = 0;
for (i = 0; i < 5; i++)
{
char * msg = "hello server....";
printf("client send msg: %s\n", msg);
if((send(sockfd, msg, strlen(msg), 0))<0)
{
perror("send()");
}
char recv_buf[MAX_BUF_LEN] = {0};
int recv_len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);
printf("client recv msg: %s\n", recv_buf);
}
return 1;
}
服务端:
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/
#define PATH "/home/unix_sock_xxxxx"
#define BACKLOG 10
#define MAX_BUF_LEN 255
int main() {
int listenfd = 0;
int connfd = 0;
struct sockaddr_un svr_addr;
struct sockaddr_un cli_addr;
memset(&svr_addr, 0, sizeof(struct sockaddr_un));
memset(&cli_addr, 0, sizeof(struct sockaddr_un));
listenfd = socket(AF_LOCAL, SOCK_STREAM, 0);
unlink(PATH);
svr_addr.sun_family = AF_LOCAL;
strncpy(svr_addr.sun_path, PATH, sizeof(svr_addr.sun_path) - 1);
bind(listenfd, (struct sockaddr*)&svr_addr, SUN_LEN(&svr_addr));
listen(listenfd, BACKLOG);
printf("server is on...\n");
int cli_len = sizeof(cli_addr);
connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &cli_len);
char recv_buf[MAX_BUF_LEN] = {0};
int recv_len = 0;
while((recv_len = recv(connfd, recv_buf, sizeof(recv_buf), 0)) > 0)
{
printf("svr %d recv %s recv_len %d\n", connfd, recv_buf, recv_len);
int ret = send(connfd, recv_buf, strlen(recv_buf), 0);
if (ret < 0)
{
perror("send failed");
exit(1);
}
memset(recv_buf, 0, sizeof(recv_buf));
}
return 1;
}
总结:和普通tcp套接字相比,不同点有family为AF_LOCAL,地址类型为sockaddr_un,同时宏SUN_LEN返回的是不包括空字符的结构体长度。其它基本一样。