source: lib/rtserver.c @ ef55d05

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ef55d05 was ef55d05, checked in by Shane Alcock <salcock@…>, 16 years ago

Added more help info - fixed major rtserver bug - added a little more documentation

  • Property mode set to 100644
File size: 4.2 KB
Line 
1#include "rtserver.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/socket.h>
5#include <time.h>
6#include <netdb.h>
7#include <netinet/in.h>
8#include <errno.h>
9
10
11/** Structure containing all the information necessary to run an rtserver */
12struct rtserver_t {
13        /** fd describing the listening socket */
14        int connect_fd;
15        /** set of client fds */
16        fd_set rt_fds;
17        /** the highest numbered fd */
18        int max_rtfds;
19        /** sockaddr used to accept incoming connections */
20        struct sockaddr_in * remote;
21};
22
23struct rtserver_t * rtserver_create (char * hostname, short port) {
24        struct rtserver_t * rtserver = malloc(sizeof(struct rtserver_t));
25        struct hostent *he;
26        int yes = 1;
27       
28        FD_ZERO(&rtserver->rt_fds);
29
30        if (hostname) {
31                if ((he=gethostbyname(hostname)) == NULL) {
32                        perror("gethostbyname");
33                        return 0;
34                }
35        }
36       
37        if ((rtserver->connect_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
38                perror("socket");
39                return 0;
40        }
41        if (setsockopt(rtserver->connect_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
42                perror("setsockopt");
43                return 0;
44        }
45        rtserver->remote = calloc(1,sizeof(struct sockaddr_in));
46        // Need to set up a listening server here
47        bzero((char *) rtserver->remote, sizeof(rtserver->remote));
48        rtserver->remote->sin_family = AF_INET;
49        if (hostname)
50                rtserver->remote->sin_addr = *((struct in_addr *)he->h_addr);
51        else 
52                rtserver->remote->sin_addr.s_addr = INADDR_ANY;
53        rtserver->remote->sin_port = htons(port);
54
55        if (bind(rtserver->connect_fd, (struct sockaddr *) rtserver->remote, sizeof(struct sockaddr_in)) < 0) {
56                perror("bind");
57                return 0;
58        }
59
60        if (listen(rtserver->connect_fd, 10) == -1) {
61                perror("listen");
62                return 0;
63        }
64       
65        rtserver->max_rtfds = rtserver->connect_fd;
66
67        return rtserver;
68}
69
70void rtserver_destroy (struct rtserver_t * rtserver) {
71        int i;
72        close(rtserver->connect_fd);
73
74        for (i=1; i <= rtserver->max_rtfds; i++) {
75                if (FD_ISSET(i, &rtserver->rt_fds)) {
76                        close(i);
77                }
78        }
79       
80        free(rtserver->remote);
81        free(rtserver);
82}
83
84int rtserver_checklisten (struct rtserver_t * rtserver) {
85        struct timeval tv;
86        int rt_fd = 0;
87        fd_set current;
88        int i;
89        int sin_size = sizeof(struct sockaddr_in);
90       
91        tv.tv_sec = 0;
92        tv.tv_usec = 10;
93       
94        FD_ZERO(&current);
95        FD_SET(rtserver->connect_fd, &current);
96       
97        do {
98                if (select(rtserver->max_rtfds + 1, &current, NULL, NULL,&tv) >=0 ) {
99                        break;
100                }
101        }
102        while (errno == EINTR);
103        for (i = 0; i <= rtserver->max_rtfds; i++) {
104                if (FD_ISSET(i, &current)) {
105                        // Got something on the listening socket
106                        if (i == rtserver->connect_fd) {
107                                if ((rt_fd = accept(i, (struct sockaddr *) rtserver->remote,
108                                                                &sin_size)) == -1) {
109                                        perror("accept");
110                                        return -1;
111                                } else {
112                                        printf("Client connected\n");
113                                        FD_SET(rt_fd, &rtserver->rt_fds);
114                                        if (rt_fd > rtserver->max_rtfds)
115                                                rtserver->max_rtfds = rt_fd;
116                                }
117                        }
118                }
119        }
120        return rt_fd;
121}
122
123int rtserver_sendclients (struct rtserver_t * rtserver, char * buffer, size_t len) {
124        fd_set current;
125        int i;
126        int numbytes = 0;
127        struct timeval tv;
128       
129        tv.tv_sec = 0;
130        tv.tv_usec = 10;
131        current = rtserver->rt_fds;
132
133        if (select(rtserver->max_rtfds + 1, NULL, &current, NULL, &tv) == -1 ) {
134                perror("select");
135                return -1;
136               
137        }
138
139        // Send the data to each ready client
140        for (i = 0; i <= rtserver->max_rtfds; i++) {
141                if (FD_ISSET(i, &current)) {
142                       
143                        // do write
144#ifndef MSG_NOSIGNAL
145#define MSG_NOSIGNAL 0
146#endif
147
148                        if ((numbytes = send(i, buffer, len, MSG_NOSIGNAL)) == -1) {
149                                perror("send");
150                                FD_CLR(i, &rtserver->rt_fds);
151                                close(i);
152                                numbytes = 0;                               
153                        }
154                }
155        }
156        return numbytes;
157}
Note: See TracBrowser for help on using the repository browser.