|
发表于 2005-1-2 00:58:36
|
显示全部楼层
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- void err_quit(const char *msg)
- {
- printf("%s\n", msg);
- exit(0);
- }
- ssize_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));
- }
- ssize_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_quit("control level != SOL_SOCKET");
- if (cmptr->cmsg_type != SCM_RIGHTS)
- err_quit("control type != SCM_RIGHTS");
- *recvfd = *((int *) CMSG_DATA(cmptr));
- } else
- *recvfd = -1; /* descriptor was not passed */
- #else
- /* *INDENT-OFF* */
- if (msg.msg_accrightslen == sizeof(int))
- *recvfd = newfd;
- else
- *recvfd = -1; /* descriptor was not passed */
- /* *INDENT-ON* */
- #endif
- return(n);
- }
- void child(int fd, int sockfd[2])
- {
- //close(sockfd[0]);
- close(fd);
-
- printf("Child %ld starting\n", getpid());
- char msg[] = "Hello world!\n";
- for (;;) {
- int conn = 0;
- char c = 0;
- ssize_t size = read_fd(sockfd[1], &c, 1, &conn);
- printf("[%d] Get connection %d\n", getpid(), conn);
- if (size == -1)
- {
- printf("[%d] Failed to read\n", getpid());
- continue;
- }
- printf("[%d] Write msg: %s\n", getpid(), msg);
- if (write(conn, msg, sizeof(msg)) == -1)
- printf("[%d] Failed to write\n", getpid());
- close(conn);
- }
- }
- void parent(int fd, int sockfd[2])
- {
- //close(sockfd[1]);
- int conn = 0;
- sockaddr_in addr;
- socklen_t size = sizeof(addr);
- while ((conn = accept(fd, (sockaddr*)&addr, &size)) != -1)
- {
- char c = '\0';
- printf("[%d] Receive connection %d\n", getpid(), conn);
- write_fd(sockfd[0], &c, 1, conn);
- close(conn);
- }
- }
- int main(int argc, char *argv[])
- {
- if (argc != 2)
- {
- printf("Usage: %s <port>\n", argv[0]);
- return -1;
- }
- int port = atoi(argv[1]);
- if (port == 0)
- {
- printf("Wrong port!\n");
- return -1;
- }
-
- int fd = socket(AF_INET, SOCK_STREAM, 0);
- if (fd == -1)
- {
- printf("Failed to create socket!\n");
- return -1;
- }
-
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(port);
- bind(fd, (sockaddr*)&addr, sizeof(addr));
- listen(fd, 5);
- int sockfd[2] = {0};
- socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
- pid_t pid = fork();
- if (pid == 0)
- {
- child(fd, sockfd);
- }
- else
- {
- parent(fd, sockfd);
- }
- return 0;
- }
复制代码
使用:
$./child 6669
测试:
$telnet 127.0.0.1 6669 |
|