本地套接字示例[来源:Advanced Linux Programming]

来源:互联网 发布:软件企业认证要求 编辑:程序博客网 时间:2024/06/06 12:57

 本地套接字示例[来源:Advanced Linux Programming]

  要通过套接字连接同一台主机上的进程,可以使用符号常量 PF_LOCAL 和 PF_UNIX所代表的本地命名空间。它们被称为本地套接字(local sockets)或者 UNIX 域套接字(UNIX-domain sockets)。它们的套接字地址用文件名表示,且只在建立连接的时候使用。
  套接字的名字在 struct sockaddr_un 结构中指定。你必须将 sun_family 字段设置为 AF_LOCAL 以表明它使用本地命名空间。该结构中的 sun_path 字段指定了套接字使用的路径,该路径长度必须不超过 108 字节。而 struct sockaddr_un 的实际长度应由UN_LENG 宏计算得到。可以使用任何文件名作为套接字路径,但是进程必须对所指定的
目录具有写权限,以便向目录中添加文件。如果一个进程要连接到一个本地套接字,则必须具有该套接字的读权限。尽管多台主机可能共享一个文件系统,只有同一台主机上运行的程序之间可以通过本地套接字通信。

 

socket-server.c

/* zzb 2011-11-17 22:30<<高级Linux编程.pdf>> page101: socket-server.c功能:本地命名空间套接字服务器*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>int server(int client_socket){int length;char *text;if(read(client_socket, &length, sizeof(length)) == 0)// 获取消息长度,保存到lengthreturn 0;text = malloc(length);// 分配用于保存信息的缓冲区read(client_socket, text, length);printf("%s\n", text);if(!strcasecmp(text, "quit"))// 忽略大小写比较字符串{free(text);// 释放缓冲区return 1;}free(text);return 0;}int main(int argc, char *argv[]){const char* const socket_name = argv[1];int sock_fd;struct sockaddr_un name;int client_sent_quit_message;if((sock_fd = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1){perror("socket");return 1;}name.sun_family = AF_LOCAL;strcpy(name.sun_path, socket_name);if(bind(sock_fd, (const struct sockaddr*)&name, SUN_LEN(&name)) == -1){perror("bind");return 1;}if(listen(sock_fd, 5) == -1){perror("listen");return 1;}do{struct sockaddr_un client_name;socklen_t client_name_len;int client_socket_fd;client_socket_fd = accept(sock_fd, (struct sockaddr*)&client_name, &client_name_len);client_sent_quit_message = server(client_socket_fd);close(client_socket_fd);}while(!client_sent_quit_message);close(sock_fd);// 关闭套接字文件unlink(socket_name);// 删除套接字文件return 0;}

 

socket-client.c

/* zzb 2011-11-17 22:37<<高级Linux编程.pdf>> page103: socket-client.c功能:本地命名空间套接字服务器*/#include <stdio.h>#include <string.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>void write_text(int socket_fd, const char* text){int length = strlen(text) + 1;write(socket_fd, &length, sizeof(length));// 写入长度信息write(socket_fd, text, length);// 写入消息}int main(int argc, char *argv[]){const char* const socket_name = argv[1];// 套接字文件路径const char* const message = argv[2];// 要发送的消息int socket_fd;struct sockaddr_un name;socket_fd = socket(PF_LOCAL, SOCK_STREAM, 0);// 创建本地套接字name.sun_family = AF_LOCAL;strcpy(name.sun_path, socket_name);connect(socket_fd, (const struct sockaddr*)&name, SUN_LEN(&name));// 连接套接字write_text(socket_fd, message);// 向套接字写入数据close(socket_fd);return 0;}


编译运行:

[zcm@socket #78]$makegcc -g   -c -o socket-server.o socket-server.cgcc -g -o socket-server socket-server.ogcc -g   -c -o socket-client.o socket-client.cgcc -g -o socket-client socket-client.o[zcm@socket #79]$./socket-server /tmp/socketwhat can you do for mewhat are\nyou doingthis program is greatQuit[zcm@socket #80]$


运行客户端:

 

[zcm@socket #19]$./socket-client /tmp/socket "what can you do for me"[zcm@socket #20]$./socket-client /tmp/socket "what are\nyou doing"[zcm@socket #21]$./socket-client /tmp/socket "this program is great"[zcm@socket #22]$./socket-client /tmp/socket "Quit"[zcm@socket #23]$