Avoid to shadow 'boolean' on weird platform (Windows)
[libmodbus.git] / tests / bandwidth-server-many-up.c
blob32d970572f3dda6b05336b25bcb671deb45842c0
1 /*
2 * Copyright © 2009-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <signal.h>
25 #include <modbus.h>
27 #if defined(_WIN32)
28 #include <ws2tcpip.h>
29 #else
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #endif
35 #define NB_CONNECTION 5
37 modbus_t *ctx = NULL;
38 int server_socket = -1;
39 modbus_mapping_t *mb_mapping;
41 static void close_sigint(int dummy)
43 if (server_socket != -1) {
44 close(server_socket);
46 modbus_free(ctx);
47 modbus_mapping_free(mb_mapping);
49 exit(dummy);
52 int main(void)
54 uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
55 int master_socket;
56 int rc;
57 fd_set refset;
58 fd_set rdset;
59 /* Maximum file descriptor number */
60 int fdmax;
62 ctx = modbus_new_tcp("127.0.0.1", 1502);
64 mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0,
65 MODBUS_MAX_READ_REGISTERS, 0);
66 if (mb_mapping == NULL) {
67 fprintf(stderr, "Failed to allocate the mapping: %s\n",
68 modbus_strerror(errno));
69 modbus_free(ctx);
70 return -1;
73 server_socket = modbus_tcp_listen(ctx, NB_CONNECTION);
75 signal(SIGINT, close_sigint);
77 /* Clear the reference set of socket */
78 FD_ZERO(&refset);
79 /* Add the server socket */
80 FD_SET(server_socket, &refset);
82 /* Keep track of the max file descriptor */
83 fdmax = server_socket;
85 for (;;) {
86 rdset = refset;
87 if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) {
88 perror("Server select() failure.");
89 close_sigint(1);
92 /* Run through the existing connections looking for data to be
93 * read */
94 for (master_socket = 0; master_socket <= fdmax; master_socket++) {
96 if (!FD_ISSET(master_socket, &rdset)) {
97 continue;
100 if (master_socket == server_socket) {
101 /* A client is asking a new connection */
102 socklen_t addrlen;
103 struct sockaddr_in clientaddr;
104 int newfd;
106 /* Handle new connections */
107 addrlen = sizeof(clientaddr);
108 memset(&clientaddr, 0, sizeof(clientaddr));
109 newfd = accept(server_socket, (struct sockaddr *)&clientaddr, &addrlen);
110 if (newfd == -1) {
111 perror("Server accept() error");
112 } else {
113 FD_SET(newfd, &refset);
115 if (newfd > fdmax) {
116 /* Keep track of the maximum */
117 fdmax = newfd;
119 printf("New connection from %s:%d on socket %d\n",
120 inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);
122 } else {
123 modbus_set_socket(ctx, master_socket);
124 rc = modbus_receive(ctx, query);
125 if (rc > 0) {
126 modbus_reply(ctx, query, rc, mb_mapping);
127 } else if (rc == -1) {
128 /* This example server in ended on connection closing or
129 * any errors. */
130 printf("Connection closed on socket %d\n", master_socket);
131 close(master_socket);
133 /* Remove from reference set */
134 FD_CLR(master_socket, &refset);
136 if (master_socket == fdmax) {
137 fdmax--;
144 return 0;