客戶端: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前面的@符號就表示占位符,不算為實際名稱。