UNP函数笔记十二: Unix域协议
来源:互联网 发布:ubuntu root密码忘记 编辑:程序博客网 时间:2024/06/05 15:00
第十五章 Unix域协议:
#include <sys/un.h>struct sockaddr_un { sa_family_t sun_family; /* AF_LOCAL */ char sun_path[104]; /* null-teminated pathname */};sun_path[0] means any-address#include <sys/socket.h>int socketpair(int family, int type, int protocol, int sockfd[2]); family: AF_LOCAL type: SOCK_STREAM, SOCK_DGRAM protocol: 0 success return non-zero, error return -1#include <sys/socket.h>struct cmsgcred { /* cannot find in Linux */ pid_t cmcred_pid; /* PID of sending process */ uid_t cmcred_uid; /* real UID of sending process */ uid_t cmcred_euid; /* effective UID of sending process */ gid_t cmcred_gid; /* read GID of sending process */ short cmcred_ngroups; /* number of groups */ gid_t cmcred_groups[CMGROUP_MAX]; /* groups */};CMGROUP_MAX is 16, cmcred_ngroups >= 1, cmcred_groups[0] is effective gid
示例:
#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include "err_exit.h"#include "my_signal.h"#define PORT 9999#define ADDR "127.0.0.1"#define MAXBACKLOG 100struct sockaddr_in serv;pid_t pid;int pipefd[2];void do_parent(void);void do_child(void);int main(int argc, char ** argv){ if (argc != 1) { printf("usage: %s\n", argv[0]); } if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) == -1) { err_exit("socketpair error"); } bzero(&serv, sizeof(serv)); serv.sin_family = AF_INET; serv.sin_port = htons(PORT); if (inet_pton(AF_INET, ADDR, &serv.sin_addr) <= 0) { err_exit("inet_pton error"); } if ((pid = fork()) < 0) { err_exit("fork error"); } else if (pid == 0) { do_child(); } else { do_parent(); } exit(0);}void parent_alrm(int signo){ return; /* just interrupt blocked connect() */}void do_parent(void){ int backlog; int j; int k; int junk; int fd[MAXBACKLOG + 1]; if (close(pipefd[0]) == -1) { err_exit("close error"); } if (my_signal(SIGALRM, parent_alrm) == SIG_ERR) { err_exit("my_signal error"); } for (backlog = 0; backlog <= 14; backlog++) { printf("backlog = %d: ", backlog); /* tell child value */ if (write(pipefd[1], &backlog, sizeof(int)) != sizeof(int)) { err_exit("write error"); } /* wait for child */ if (read(pipefd[1], &junk, sizeof(int)) < 0) { err_exit("read error"); } for (j = 1; j <= MAXBACKLOG; j++) { if ((fd[j] = socket(AF_INET, SOCK_STREAM, 0)) == -1) { err_exit("socket error"); } alarm(2); if (connect(fd[j], (struct sockaddr *)&serv, sizeof(serv)) < 0) { if (errno != EINTR) { printf("connect error, j = %d\n", j); exit(1); } printf("timeout, %d connections completed\n", j-1); for (k = 1; k <= j; k++) { if (close(fd[k]) == -1) { err_exit("close error"); } } break; /* next value of backlog */ } alarm(0); } if (j > MAXBACKLOG) { printf("%d connections?\n", MAXBACKLOG); } } backlog = -1; /* tell child we're all done */ if (write(pipefd[1], &backlog, sizeof(int)) != sizeof(int)) { err_exit("write error"); }}void do_child(void){ int listenfd; int backlog; int junk; const int on = 1; if (close(pipefd[1]) == -1) { err_exit("close error"); } /* wait for parent */ if (read(pipefd[0], &backlog, sizeof(int)) != sizeof(int)) { err_exit("read error"); } while (backlog >= 0) { if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { err_exit("socket error"); } if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) { err_exit("setsockopt error"); } if (bind(listenfd, (struct sockaddr *)&serv, sizeof(serv)) == -1) { err_exit("bind error"); } if (listen(listenfd, backlog) == -1) { /* start the listen */ err_exit("listen error"); } /* tell parent */ if (write(pipefd[0], &junk, sizeof(int)) != sizeof(int)) { err_exit("write error"); } /* just wait for parent */ if (read(pipefd[0], &backlog, sizeof(int)) != sizeof(int)) { err_exit("read error"); } /* closes all queued connections, too */ if (close(listenfd) == -1) { err_exit("close error"); } }}
#include <sys/socket.h>#include <sys/param.h>#include "err_exit.h"#define HAVE_MSGHDR_MSG_CONTROL 1ssize_t write_fd(int fd, void * ptr, size_t nbytes, int sendfd){ struct msghdr msg; struct iovec iov[1];#ifdef HAVE_MSGHDR_MSG_CONTROL union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; struct cmsghdr * cmptr; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); cmptr = CMSG_FIRSTHDR(&msg); cmptr->cmsg_len = CMSG_LEN(sizeof(int)); cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; *((int *)CMSG_DATA(cmptr)) = sendfd;#else msg.msg_accrights = (caddr_t) &sendfd; msg.msg_accrightslen = sizeof(int);#endif msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; return(sendmsg(fd, &msg, 0));}
#include "err_exit.h"#include "write_fd.h"int main(int argc, char ** argv){ int fd; if (argc != 4) { printf("openfile <sockfd#> <filename> <mode>\n"); exit(1); } if ((fd = open(argv[2], atoi(argv[3]))) < 0) { exit(errno > 0 ? errno : 255); } if (write_fd(atoi(argv[1]), "", 1, fd) < 0) { exit(errno > 0 ? errno : 255); } exit(0);}
#include <sys/socket.h>#include <sys/param.h>#include "err_exit.h"#define HAVE_MSGHDR_MSG_CONTROL 1ssize_t read_fd(int fd, void * ptr, size_t nbytes, int * recvfd){ struct msghdr msg; struct iovec iov[1]; ssize_t n;#ifdef HAVE_MSGHDR_MSG_CONTROL union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; struct cmsghdr * cmptr; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control);#else int newfd; msg.msg_accrights = (caddr_t) &newfd; msg.msg_accrightslen = sizeof(int);#endif msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; if ((n = recvmsg(fd, &msg, 0)) <= 0) { return(n); }#ifdef HAVE_MSGHDR_MSG_CONTROL if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { if (cmptr->cmsg_level != SOL_SOCKET) { err_exit("control level != SOL_SOCKET"); } if (cmptr->cmsg_type != SCM_RIGHTS) { err_exit("control type != SCM_RIGHTS"); } *recvfd = *((int *)CMSG_DATA(cmptr)); } else { *recvfd = -1; /* descriptor was not passed */ }#else if (msg.msg_accrightslen == sizeof(int)) { *recvfd = newfd; } else { *recvfd = -1; /* descriptor was not passed */ }#endif return(n);}
#include <sys/socket.h>#include <wait.h>#include <unistd.h>#include "err_exit.h"int my_open(const char * pathname, int mode){ int fd; int sockfd[2]; int status; pid_t childpid; char c; char argsockfd[10]; char argmode[10]; if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) == -1) { err_exit("socketpair error"); } if ((childpid = fork()) < 0) { err_exit("fork error"); } else if (childpid == 0) { if (close(sockfd[0]) == -1) { err_exit("close error"); } snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]); snprintf(argmode, sizeof(argmode), "%d", mode); execl("./openfile", "openfile", argsockfd, pathname, argmode, NULL); err_exit("execl error"); } if (close(sockfd[1]) == -1) { err_exit("close error"); } if (waitpid(childpid, &status, 0) <= 0) { err_exit("waitpid error"); } if (WIFEXITED(status) == 0) { err_exit("child did not terminate"); } if ((status = WEXITSTATUS(status)) == 0) { if (read_fd(sockfd[0], &c, 1, &fd) <= 0) { err_exit("read_fd error"); } } else { errno = status; /* set errno value from child's status */ fd = -1; } if (close(sockfd[0]) == -1) { err_exit("close error"); } return(fd);}
#include <fcntl.h>#include <unistd.h>#include "err_exit.h"#include "myopen.h"#define BUFFSIZE 4096int main(int argc, char ** argv){ int fd; int n; char buff[BUFFSIZE]; if (argc != 2) { printf("usage: mycat <pathname>\n"); exit(1); } if ((fd = my_open(argv[1], O_RDONLY)) < 0) { printf("cannot open %s\n", argv[1]); exit(1); } while ((n = read(fd, buff, BUFFSIZE)) > 0) { if (write(STDOUT_FILENO, buff, n) != n) { err_exit("write error"); } } if (n < 0) { err_exit("read error"); } exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"int main(int argc, char ** argv){ int sockfd; socklen_t len; struct sockaddr_un addr1; struct sockaddr_un addr2; if (argc != 2) { printf("usage: unixbind <pathname>\n"); exit(1); } if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { err_exit("socket error"); } unlink(argv[1]); /* OK if this fails */ bzero(&addr1, sizeof(addr1)); addr1.sun_family = AF_LOCAL; strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1); if (bind(sockfd, (struct sockaddr *)&addr1, SUN_LEN(&addr1)) == -1) { err_exit("bind error"); } len = sizeof(addr2); if (getsockname(sockfd, (struct sockaddr *)&addr2, &len) == -1) { err_exit("getsockname error"); } printf("bound name = %s, returned len = %d\n", addr2.sun_path, len); exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXDG_PATH "/tmp/uinxdg"int main(int argc, char ** argv){ int sockfd; struct sockaddr_un servaddr; struct sockaddr_un cliaddr; if ((sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) { err_exit("socket error"); } unlink(UNIXDG_PATH); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXDG_PATH); if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("bind error"); } dg_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXDG_PATH "/tmp/uinxdg"int main(int argc, char ** argv){ int sockfd; struct sockaddr_un cliaddr; struct sockaddr_un servaddr; if ((sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) { err_exit("socket error"); } bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */ cliaddr.sun_family = AF_LOCAL; strcpy(cliaddr.sun_path, tmpnam(NULL)); if (bind(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) == -1) { err_exit("bind error"); } bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */ servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXDG_PATH); dg_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#define UNIXSTR_PATH "/tmp/unixstr"int main(int argc, char ** argv){ int sockfd; struct sockaddr_un servaddr; if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { err_exit("socket error"); } bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXSTR_PATH); if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("connect error"); } str_cli(stdin, sockfd); exit(0);}
#include <sys/socket.h>#include <sys/un.h>#include "err_exit.h"#include "my_signal.h"#define LISTENQ 1024#define UNIXSTR_PATH "/tmp/unixstr"void sig_chld(int signo){ pid_t pid; int stat; while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) { printf("child %d terminated\n", pid); } return;}int main(int argc, char ** argv){ int listenfd; int connfd; pid_t childpid; socklen_t clilen; struct sockaddr_un cliaddr; struct sockaddr_un servaddr; if ((listenfd = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { err_exit("socket error"); } unlink(UNIXSTR_PATH); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, UNIXSTR_PATH); if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { err_exit("bind error"); } if (listen(listenfd, LISTENQ) == -1) { err_exit("listen error"); } if (my_signal(SIGCHLD, sig_chld) == SIG_ERR) { err_exit("my_signal error"); } for ( ; ; ) { clilen = sizeof(cliaddr); if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen)) < 0) { if (errno == EINTR) { continue; /* back to for() */ } else { err_exit("accept error"); } } if ((childpid = fork()) < 0) { err_exit("fork error"); } else if (childpid == 0) { if (close(listenfd) == -1) { err_exit("close error"); } str_echo(connfd); exit(0); } if (close(connfd) == -1) { err_exit("close error"); } }}
#include <sys/socket.h>#include "err_exit.h"#define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))ssize_t read_cred(int fd, void * ptr, size_t nbytes, struct cmsgcred * cmsgcredptr){ struct msghdr msg; struct iovec iov[1]; char control[CONTROL_LEN]; int n; msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = control; msg.msg_controllen = sizeof(control); msg.msg_flags = 0; if ((n = recvmsg(fd, &msg, 0)) < 0) { return(n); } cmsgcredptr->cmcred_ngroups = 0; /* indicates no credentials returned */ if (cmsgcredptr && msg.msg_controllen > 0) { struct cmsghdr * cmptr = (struct cmsghdr *)control; if (cmptr->cmsg_len < CONTROL_LEN) { printf("control length = %d\n", cmptr->cmsg_len); exit(1); } if (cmptr->cmsg_level != SOL_SOCKET) { err_exit("control level != SOL_SOCKET"); } if (cmptr->cmsg_type != SCM_CREDS) { err_exit("control type != SCM_CREDS"); } memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred)); } return(n);}
#include <sys/socket.h>#include "err_exit.h"#include "writen.h"#include "readcred.h"ssize_t read_cred(int, void *, size_t, struct cmsgcred *);#define MAXLINE 4096void str_echo(int sockfd){ ssize_t n; int i; char buf[MAXLINE]; struct cmsgcred cred;again: while ((n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) { if (cred.cmcred_ngroups == 0) { printf("(no credentials returned)\n"); } else { printf("PID of sender = %d\n", cred.cmcred_pid); printf("real user ID = %d\n", cred.cmcred_uid); printf("real group ID = %d\n", cred.cmcred_gid); printf("effective user ID = %d\n", cred.cmcred_euid); printf("%d groups:", cred.cmcred_ngroups - 1); for (i = 1; i < cred.cmcred_ngroups; i++) { printf(" %d", cred.cmcred_groups[i]); } printf("\n"); } if (writen(sockfd, buf, n) != n) { err_exit("write error"); } } if (n < 0 && errno == EINTR) { goto again; } else if (n < 0) { err_exit("str_echo: read error"); }}
- UNP函数笔记十二: Unix域协议
- UNP学习笔记(第十五章 UNIX域协议)
- UNP卷1:第十五章(unix域协议)
- UNP函数笔记十六: 线程
- UNP总结 Chapter 15~17 Unix域协议、非阻塞式I/O、ioctl操作
- UNP函数笔记五: 套接字选项
- UNP函数笔记十四: 带外数据
- unp 笔记
- 《UNIX网络编程 卷1》 笔记: UNIX域协议
- HTTP协议学习笔记十二
- UNP函数笔记十一: 高级I/O函数
- UNP笔记2——TCP套接口函数
- [UNP笔记]I/O复用,select和poll函数
- UNP函数笔记一: 套接字编程简介
- UNP函数笔记二: 基本TCP套接字编程
- UNP函数笔记三: TCP客户/服务器程序示例
- UNP函数笔记六: 基本UDP套接字编程
- UNP函数笔记七: 基本SCTP套接字编程
- Creating Excel File Through XML
- C#跨窗体操作(引用传递)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- 解决backspace和上下键使用出现乱码
- linux I2C 驱动之----i2c_client 的注册
- UNP函数笔记十二: Unix域协议
- C#3.0学习笔记(11)枚举数和foreach语句实现原理
- REST - GET Parameter
- 恢复桌面右键新建菜单中的“新建文本”
- MySQL Key值(PRI, UNI, MUL)的含义
- Stripes学习(一)
- CXF 入门:HelloWorld接口发布
- C#操作数据库基础实例《密码管理工具》
- Tomcat 负载均衡