原執行個體在APUE(第三版)17.2 UNIX域套接字
1、使用UNIX與套接字輪詢XSI消息隊列(poll版,原版)
<code>#include "apue.h"</code>
<code>#include <poll.h></code>
<code>#include <pthread.h></code>
<code>#include <sys/msg.h></code>
<code>#include <sys/socket.h></code>
<code>#define NQ 3 //隊列的數量</code>
<code>#define MAXMSZ 512 //消息的最大長度</code>
<code>#define KEY 0x123 //消息隊列的第一個key值</code>
<code>struct</code> <code>threadinfo {</code>
<code> </code><code>int</code> <code>qid;</code>
<code> </code><code>int</code> <code>fd;</code>
<code>};</code>
<code>struct</code> <code>mymesg {</code>
<code> </code><code>long</code> <code>mtype;</code>
<code> </code><code>char</code> <code>mtext[MAXMSZ];</code>
<code>void</code> <code>*helper(</code><code>void</code> <code>*arg)</code>
<code>{</code>
<code> </code><code>int</code> <code>n;</code>
<code> </code><code>struct</code> <code>mymesg m;</code>
<code> </code><code>struct</code> <code>threadinfo *tip = arg;</code>
<code> </code><code>for</code> <code>(;;) {</code>
<code> </code><code>printf</code><code>(</code><code>"helper qid %d, fd %d, tid %u\n"</code><code>, tip->qid, tip->fd, (unsigned)pthread_self());</code>
<code> </code><code>memset</code><code>(&m, 0, </code><code>sizeof</code><code>(m));</code>
<code> </code><code>if</code> <code>((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0) {</code>
<code> </code><code>err_sys(</code><code>"msgrcv error"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>if</code> <code>(write(tip->fd, m.mtext, n) < 0) {</code>
<code> </code><code>err_sys(</code><code>"write error"</code><code>);</code>
<code> </code><code>}</code>
<code>}</code>
<code>int</code> <code>main()</code>
<code> </code><code>int</code> <code>i, n, err;</code>
<code> </code><code>int</code> <code>fd[2];</code>
<code> </code><code>int</code> <code>qid[NQ];</code>
<code> </code><code>struct</code> <code>pollfd pfd[NQ];</code>
<code> </code><code>struct</code> <code>threadinfo ti[NQ];</code>
<code> </code><code>pthread_t tid[NQ];</code>
<code> </code><code>char</code> <code>buf[MAXMSZ];</code>
<code> </code><code>for</code> <code>(i = 0; i < NQ; ++i) {</code>
<code> </code><code>if</code> <code>((qid[i] = msgget((KEY+i), IPC_CREAT|0666)) < 0) { </code><code>//建立一個新隊列</code>
<code> </code><code>err_sys(</code><code>"msgget error"</code><code>);</code>
<code> </code><code>printf</code><code>(</code><code>"queue %d ID is %d\n"</code><code>, i, qid[i]);</code>
<code> </code><code>if</code> <code>(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) { </code><code>//建立UNXI域套接字(fd管道)</code>
<code> </code><code>err_sys(</code><code>"socketpair error"</code><code>);</code>
<code> </code><code>printf</code><code>(</code><code>"fd[0]:%d\n"</code><code>, fd[0]);</code>
<code> </code><code>printf</code><code>(</code><code>"fd[1]:%d\n"</code><code>, fd[1]);</code>
<code> </code><code>pfd[i].fd = fd[0];</code>
<code> </code><code>pfd[i].events = POLLIN;</code>
<code> </code><code>ti[i].qid = qid[i];</code>
<code> </code><code>ti[i].fd = fd[1];</code>
<code> </code><code>if</code> <code>((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0) { </code><code>//建立線程</code>
<code> </code><code>err_exit(err, </code><code>"pthread_create error"</code><code>);</code>
<code> </code><code>if</code> <code>(poll(pfd, NQ, -1) < 0) { </code><code>//等待事件發生</code>
<code> </code><code>err_sys(</code><code>"poll error"</code><code>);</code>
<code> </code><code>for</code> <code>(i = 0; i < NQ; ++i) {</code>
<code> </code><code>//printf("i:%d\n", i);</code>
<code> </code><code>if</code> <code>(pfd[i].revents & POLLIN) {</code>
<code> </code><code>if</code> <code>((n = read(pfd[i].fd, buf, </code><code>sizeof</code><code>(buf))) < 0) {</code>
<code> </code><code>err_sys(</code><code>"read error"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>buf[n] = 0;</code>
<code> </code><code>printf</code><code>(</code><code>"queue %d id %d, message %s\n"</code><code>, i, qid[i], buf);</code>
<code> </code><code>}</code>
<code> </code><code>exit</code><code>(0);</code>
編譯指令:
<code>gcc pollmsg.c -o pollmsg -lapue -lpthread -std=c99</code>
2、使用UNIX與套接字輪詢XSI消息隊列(epoll版,改版)
<code>#include <sys/epoll.h></code>
<code>#define FDSIZE 1000</code>
<code>#define EPOLLEVENTS 100</code>
<code> </code><code>int</code> <code>epollfd;</code>
<code> </code><code>struct</code> <code>epoll_event events[EPOLLEVENTS];</code>
<code> </code><code>epollfd = epoll_create(FDSIZE); </code><code>//建立epoll檔案描述符</code>
<code> </code><code>struct</code> <code>epoll_event ev;</code>
<code> </code><code>ev.events = EPOLLIN;</code>
<code> </code><code>ev.data.fd = fd[0];</code>
<code> </code><code>epoll_ctl(epollfd, EPOLL_CTL_ADD, fd[0], &ev); </code><code>//注冊fd[0]到epoll</code>
<code> </code><code>} </code>
<code> </code><code>int</code> <code>occurred;</code>
<code> </code><code>if</code> <code>((occurred = epoll_wait(epollfd, events, EPOLLEVENTS, -1)) < 0) { </code><code>//等待事件發生</code>
<code> </code><code>err_sys(</code><code>"epoll error"</code><code>);</code>
<code> </code><code>if</code> <code>(occurred == 0) {</code>
<code> </code><code>err_sys(</code><code>"epoll timeout"</code><code>);</code>
<code> </code><code>for</code> <code>(i = 0; i < occurred; ++i) {</code>
<code> </code><code>if</code> <code>(events[i].events & EPOLLIN) {</code>
<code> </code><code>if</code> <code>((n = read(events[i].data.fd, buf, </code><code>sizeof</code><code>(buf))) < 0) {</code>
<code> </code><code>printf</code><code>(</code><code>"main thread %u, message %s\n"</code><code>, (unsigned)pthread_self(), buf);</code>
<code>gcc epollmsg.c -o epollmsg -lapue -lpthread -std=c99</code>
3、給XSI消息隊列發送消息(測試程式,原版)
<code>#define MAXMSZ 512</code>
<code>int</code> <code>main(</code><code>int</code> <code>argc, </code><code>char</code> <code>*argv[])</code>
<code> </code><code>key_t key;</code>
<code> </code><code>long</code> <code>qid;</code>
<code> </code><code>size_t</code> <code>nbytes;</code>
<code> </code><code>if</code> <code>(argc != 3) {</code>
<code> </code><code>fprintf</code><code>(stderr, </code><code>"usage: sendmsg KEY message\n"</code><code>);</code>
<code> </code><code>exit</code><code>(1);</code>
<code> </code><code>key = </code><code>strtol</code><code>(argv[1], NULL, 0);</code>
<code> </code><code>//printf("key:0x%08X\n", (unsigned )key);</code>
<code> </code><code>if</code> <code>((qid = msgget(key, 0)) < 0) { </code><code>//打開一個現有隊列</code>
<code> </code><code>err_sys(</code><code>"can't open queue key %s"</code><code>, argv[1]);</code>
<code> </code><code>memset</code><code>(&m, 0, </code><code>sizeof</code><code>(m));</code>
<code> </code><code>strncpy</code><code>(m.mtext, argv[2], MAXMSZ - 1);</code>
<code> </code><code>nbytes = </code><code>strlen</code><code>(m.mtext);</code>
<code> </code><code>m.mtype = 1;</code>
<code> </code><code>//printf("qid:%ld\n", qid);</code>
<code> </code><code>if</code> <code>(msgsnd(qid, &m, nbytes, 0) < 0) { </code><code>//發送消息給指定消息隊列</code>
<code> </code><code>err_sys(</code><code>"can't send message"</code><code>);</code>
<code>gcc sendmsg.c -o sendmsg -lapue -std=c99</code>
相關閱讀:
本文轉自walker snapshot部落格51CTO部落格,原文連結http://blog.51cto.com/walkerqt/1768445如需轉載請自行聯系原作者
RQSLT