標籤:
前言介紹:
1。UNIX域通訊端與TCP通訊端相比較,在同一台主機的傳輸四度前者是後者的兩倍
2.UNIX域通訊端可以在同一台主機上各進程間傳遞描述符
3.UNIX域通訊端與傳統通訊端的區別是用路徑名來表示協議族的描述。
UNIX域地址結構
#define UNIX_PATH_MAX 108struct sockaddr_un{ sa_family_t sun_family; /* AF_UNIX*/ char sun_path[UNIX_PATH_MAX]; /*pathname*/}
下面 我們寫一個簡單的回射伺服器來練習一下
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/un.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)void echo_srv(int conn){ char recvbuf[1024]; int ret; while(1) { memset(recvbuf, 0, sizeof(recvbuf)); ret = read(conn, recvbuf, 1024); if(ret ==-1) { if(errno == EINTR) continue; ERR_EXIT("read"); }else if(ret == 0) { close(conn); printf("client close\n"); } fputs(recvbuf, stdout); write(conn, recvbuf, ret); }int main(int argc, const char *argv[]){ //使用UNIX域通訊端,在申請通訊端時就與TCP不同 // 需要使用一個PF_UNIX的宏,而不是pf_inet int listenfd = socket(PF_UNIX, SOCK_STREAM, 0); if(listenfd < 0) ERR_EXIT("SoCKET"); struct sockaddr_un servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sun_family = AF_UNIX; strcpy(servaddr.sun_path, "test_socket"); if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) ERR_EXIT("bind"); if(listen(listenfd, SOMAXCONN) < 0) ERR_EXIT("listen"); int conn; pid_t pid; while(1) { conn = accpet(listenfd, NULL, NULl); if(conn == -1) { if(errno == EINTR) continue; ERR_EXIT("accept"); } pid = fork(); if(pid == -1) ERR_EXIT("fork"); if(pid == 0) { close(listenfd); echo_srv(conn); exit(EXIT_SUCCESS); }else if(pid > 0) { close(conn); } } return 0}
注意:
1.bind成功將會建立一個檔案, 許可權為0777, & umask = 755
2.sun_path最好用一個絕對路徑
3.UNIX域協議支援流式通訊端與報式套介面
4.UNIX與流式通訊端connect發現監聽隊列滿時,會立刻返回一個ECONNREFUSED, 這和TCP不同
如果監聽隊列滿, 會忽略到來的SYN, 這導致對方重傳SYN;
LINUX學習:UNIX域協議