在Ubuntu下实现本地套接字(socket)通信以及遇到的问题!

来源:互联网 发布:黄药师软件多少钱 编辑:程序博客网 时间:2024/05/08 09:59

客户端: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 style="color:#ff0000;">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
前面的@符号就表示占位符,不算为实际名称。




0 0
原创粉丝点击