source: network-demos/select/test.c @ 24de663

4.11netdemos-4-5-branchnetwork-demos-4-10-branchnetwork-demos-4-6-branchnetwork-demos-4-7-branchnetwork-demos-4-8-branchnetwork-demos-4-9-branchrtems-4-5-branch
Last change on this file since 24de663 was 24de663, checked in by Joel Sherrill <joel.sherrill@…>, on 06/11/99 at 14:10:59

Patch from Ian Lance Taylor <ian@…> to test new "interrupt-ish"
driven select on socket support.

After the patch to RTEMS, I have appended a patch to
netdemos-19990407/select/test.c to test the new functionality and
demonstrate one way it might be used. To run the new test instead of
the select test, change doSocket to call echoServer2 instead of
echoServer.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Test RTEMS networking
3 *
4 * This program may be distributed and used for any purpose.
5 * I ask only that you:
6 *      1. Leave this author information intact.
7 *      2. Document any changes you make.
8 *
9 * W. Eric Norum
10 * Saskatchewan Accelerator Laboratory
11 * University of Saskatchewan
12 * Saskatoon, Saskatchewan, CANADA
13 * eric@skatter.usask.ca
14 *
15 *  $Id$
16 */
17
18#include <stdio.h>
19#include <string.h>
20#include <errno.h>
21#include <unistd.h>
22#include <rtems.h>
23#include <rtems/rtems_bsdnet.h>
24#include <rtems/error.h>
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <netinet/in.h>
28
29#define BASE_PORT       24742
30#define CLIENT_COUNT    2
31
32static int clientfd[CLIENT_COUNT];
33
34static void
35getClients (unsigned short port)
36{
37        int s, s1;
38        struct sockaddr_in myAddr, farAddr;
39        int addrlen;
40        int clientCount;
41
42        printf ("Create socket.\n");
43        s = socket (AF_INET, SOCK_STREAM, 0);
44        if (s < 0)
45                rtems_panic ("Can't create socket: %s", strerror (errno));
46        myAddr.sin_family = AF_INET;
47        myAddr.sin_port = htons (port);
48        myAddr.sin_addr.s_addr = INADDR_ANY;
49        memset (myAddr.sin_zero, '\0', sizeof myAddr.sin_zero);
50        printf ("Bind socket.\n");
51        if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0)
52                rtems_panic ("Can't bind socket: %s", strerror (errno));
53        printf ("Listen.\n");
54        if (listen (s, 2) < 0)
55                rtems_panic ("Can't listen on socket: %s", strerror (errno));
56
57        /*
58         * Accumulate clients
59         */
60        for (clientCount = 0 ; clientCount < CLIENT_COUNT ; clientCount++) {
61                printf ("Accept.\n");
62                addrlen = sizeof farAddr;
63                s1 = accept (s, (struct sockaddr *)&farAddr, &addrlen);
64                if (s1 < 0)
65                        rtems_panic ("Can't accept connection: %s", strerror (errno));
66                else
67                        printf ("ACCEPTED:%lX\n", ntohl (farAddr.sin_addr.s_addr));
68                clientfd[clientCount] = s1;
69        }
70
71        close (s);
72}
73
74static void
75echoServer (unsigned short port)
76{
77        fd_set clientfdset;
78        int clientCount;
79        int topfd = 0;
80
81        getClients (port);
82
83        FD_ZERO (&clientfdset);
84
85        for (clientCount = 0 ; clientCount < CLIENT_COUNT ; clientCount++) {
86                int s1;
87
88                s1 = clientfd[clientCount];
89                FD_SET (s1, &clientfdset);
90                if (s1 > topfd)
91                        topfd = s1;
92        }
93
94        /*
95         * Run clients
96         */
97        for (;;) {
98                fd_set readfdset;
99                struct timeval tv;
100                int n;
101                int i;
102
103                tv.tv_sec = 5;
104                tv.tv_usec = 0;
105                readfdset = clientfdset;
106                n = select (topfd + 1, &readfdset, NULL, NULL, &tv);
107                if (n < 0) {
108                        printf ("Select() error: %s\n", strerror (errno));
109                        return;
110                }
111                if (n == 0) {
112                        printf ("Timeout\n");
113                        continue;
114                }
115       
116                printf ("Activity on %d file descriptor%s.\n", n, n == 1 ? "" : "s");
117                for (i = 0 ; n && (i < CLIENT_COUNT) ; i++) {
118                        int fd = clientfd[i];
119                        if (FD_ISSET (fd, &readfdset)) {
120                                char buf[200];
121                                int nread;
122
123                                printf ("Activity on file descriptor %d.\n", fd);
124                                n--;
125                                nread = read (fd, buf, sizeof buf);
126                                if (nread < 0) {
127                                        printf ("Read error %s.\n", strerror (errno));
128                                        return;
129                                }
130                                if (nread == 0) {
131                                        printf ("EOF\n");
132                                        FD_CLR (fd, &clientfdset);
133                                        close (fd);
134                                        if (--clientCount == 0)
135                                                return;
136                                }
137                                printf ("Read %d.\n", nread);
138                        }
139                }
140        }
141}
142
143static rtems_id tid;
144
145static void
146wakeup (struct socket *so, caddr_t arg)
147{
148        rtems_event_send (tid, RTEMS_EVENT_0 + (int) arg);
149}
150
151static void
152echoServer2 (port)
153{
154        struct sockwakeup sw, sw2;
155        int swlen;
156        int clientCount;
157        rtems_event_set clientEvents;
158
159        getClients (port);
160
161        sw.sw_pfn = &wakeup;
162        clientEvents = 0;
163        for (clientCount = 0 ; clientCount < CLIENT_COUNT ; clientCount++) {
164                sw.sw_arg = (caddr_t) clientCount;
165                if (setsockopt (clientfd[clientCount], SOL_SOCKET,
166                                SO_RCVWAKEUP, &sw, sizeof sw) < 0)
167                        rtems_panic ("setsockopt failed: %s",
168                                     strerror (errno));
169                swlen = sizeof sw2;
170                if (getsockopt (clientfd[clientCount], SOL_SOCKET,
171                                SO_RCVWAKEUP, &sw2, &swlen) < 0)
172                        rtems_panic ("getsockopt failed: %s",
173                                     strerror (errno));
174                if (swlen != sizeof sw2
175                    || sw2.sw_pfn != &wakeup
176                    || (int) sw2.sw_arg != clientCount)
177                        rtems_panic ("getsockopt mismatch");
178
179                clientEvents |= RTEMS_EVENT_0 + clientCount;
180        }
181
182        if (rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_LOCAL_NODE, &tid)
183            != RTEMS_SUCCESSFUL)
184          rtems_panic ("rtems_task_ident failed");
185
186        for (;;) {
187                rtems_event_set events;
188                rtems_status_code status;
189                int i;
190
191                status = rtems_event_receive (clientEvents,
192                                              RTEMS_WAIT | RTEMS_EVENT_ANY,
193                                              RTEMS_MILLISECONDS_TO_TICKS (5000),
194                                              &events);
195
196                if (status == RTEMS_TIMEOUT) {
197                        printf ("Timeout\n");
198                        continue;
199                }
200
201                for (i = 0; i < CLIENT_COUNT; ++i) {
202                        if (events == 0)
203                                break;
204                        if (events & (i + RTEMS_EVENT_0)) {
205                                int fd;
206                                char buf[200];
207                                int nread;
208
209                                fd = clientfd[i];
210                                printf ("Activity on file descriptor %d.\n", fd);
211                                events &= ~ (i + RTEMS_EVENT_0);
212                                nread = read (fd, buf, sizeof buf);
213                                if (nread < 0) {
214                                        printf ("Read error %s.\n", strerror (errno));
215                                        return;
216                                }
217                                if (nread == 0) {
218                                        printf ("EOF\n");
219                                        clientEvents &= ~ (i + RTEMS_EVENT_0);
220                                        close (fd);
221                                        if (--clientCount == 0)
222                                                return;
223                                }
224                                printf ("Read %d.\n", nread);
225                        }
226                }
227        }
228}
229
230void
231doSocket (void)
232{
233        echoServer (BASE_PORT);
234}
Note: See TracBrowser for help on using the repository browser.