客戶端:client.c
#include<stdio.h> #include<sys/socket.h> #include<sys/types.h> #include<sys/un.h> #include<unistd.h> #include<stdlib.h> int main(){ int sockfd; int len; struct sockaddr_un address; int result; char ch='A'; sockfd=socket(AF_UNIX,SOCK_STREAM,0); address.sun_family=AF_UNIX; strcpy(address.sun_path,"server_socket"); len=sizeof(address); result=connect(sockfd,(struct sockaddr *)&address,len); if(result==-1){ perror("oops:client1"); exit(1); } write(sockfd,&ch,1); read(sockfd,&ch,1); printf("char from server = %c \n",ch); close(sockfd); exit(0); }服務端:server.c
#include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/un.h> #include<unistd.h> int main(){ int server_sockfd,client_sockfd; int server_len,client_len; struct sockaddr_un server_address; struct sockaddr_un client_address; <span >unlink("server_socket");// 創建本地套接字</span> server_sockfd=socket(AF_UNIX,SOCK_STREAM,0); server_address.sun_family=AF_UNIX; strcpy(server_address.sun_path,"server_socket"); server_len=sizeof(server_address); bind(server_sockfd,(struct sockaddr *)&server_address,server_len); listen(server_sockfd,5); while(1){ char ch; printf("server watting\n"); client_len=sizeof(client_address); client_sockfd=accept(server_sockfd, (struct sockaddr *)&client_address,&client_len); read(client_sockfd,&ch,1); ch++; write(client_sockfd,&ch,1); close(client_sockfd); } }我在ubuntu下運行上述代碼時,它會報錯:找不到server_socket這個套接字,但同樣的代碼在centos下能運行,原來是我在ubuntu中運行程序的用戶不具有文件的讀寫權限。
所以我們需要把創建的套接字放在用戶都能訪問的 /tmp目錄下面(如下第一種方法)。
參考網址:http://blog.chinaunix.net/uid-26808060-id-4065810.html
socket進程通信命名方式有兩種:
一、普通的命名
socket會根據此命名創建一個同名的socket文件,客戶端連接的時候通過讀取該socket文件連接到socket服務端。這種方式的弊端是服務端必須對socket文件的路徑具備寫權限,客戶端必須知道socket文件路徑,且必須對該路徑有讀權限。
代碼實現:
server_address.sun_family = AF_UNIX; strcpy(server_addr.sun_path,"/tmp/UNIX.domain"); server_len = sizeof(struct sockaddr_un);二、抽象命名空間
這種方式不需要創建socket文件,只需要命名一個全局名字,即可讓客戶端根據此名字進行連接。後者的實現過程與前者的差別是,後者在對地址結構成員sun_path數組賦值的時候,必須把第一個字節置0,即sun_path[0] = 0
代碼實現:
server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, SERVER_NAME); server_addr.sun_path[0]=0; //server_len = sizeof(server_addr); server_len = strlen(SERVER_NAME) + offsetof(struct sockaddr_un, sun_path);其中,offsetof函數在#include 頭文件中定義。因第二種方式的首字節置0,我們可以在命名字符串SERVER_NAME前添加一個占位字符串,例如:
#define SERVER_NAME @socket_server前面的@符號就表示占位符,不算為實際名稱。