source: lib/rtserver.c @ 53f8305

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 53f8305 was 53f8305, checked in by Daniel Lawson <dlawson@…>, 15 years ago

patches for BSD compilation

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