Fix too short uint8_t for rsp_length (bug introduced by 018cdd6)
[libmodbus.git] / tests / bandwidth-server-many-up.c
blobb279d0ad3e3d32f170afedb1952fa24f0b19ce97
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;
39 modbus_mapping_t *mb_mapping;
41 static void close_sigint(int dummy)
43 close(server_socket);
44 modbus_free(ctx);
45 modbus_mapping_free(mb_mapping);
47 exit(dummy);
50 int main(void)
52 int master_socket;
53 int rc;
54 fd_set refset;
55 fd_set rdset;
57 /* Maximum file descriptor number */
58 int fdmax;
60 ctx = modbus_new_tcp("127.0.0.1", 1502);
62 mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 0,
63 MODBUS_MAX_READ_REGISTERS, 0);
64 if (mb_mapping == NULL) {
65 fprintf(stderr, "Failed to allocate the mapping: %s\n",
66 modbus_strerror(errno));
67 modbus_free(ctx);
68 return -1;
71 server_socket = modbus_tcp_listen(ctx, NB_CONNECTION);
73 signal(SIGINT, close_sigint);
75 /* Clear the reference set of socket */
76 FD_ZERO(&refset);
77 /* Add the server socket */
78 FD_SET(server_socket, &refset);
80 /* Keep track of the max file descriptor */
81 fdmax = server_socket;
83 for (;;) {
84 rdset = refset;
85 if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) {
86 perror("Server select() failure.");
87 close_sigint(1);
90 /* Run through the existing connections looking for data to be
91 * read */
92 for (master_socket = 0; master_socket <= fdmax; master_socket++) {
94 if (FD_ISSET(master_socket, &rdset)) {
95 if (master_socket == server_socket) {
96 /* A client is asking a new connection */
97 socklen_t addrlen;
98 struct sockaddr_in clientaddr;
99 int newfd;
101 /* Handle new connections */
102 addrlen = sizeof(clientaddr);
103 memset(&clientaddr, 0, sizeof(clientaddr));
104 newfd = accept(server_socket, (struct sockaddr *)&clientaddr, &addrlen);
105 if (newfd == -1) {
106 perror("Server accept() error");
107 } else {
108 FD_SET(newfd, &refset);
110 if (newfd > fdmax) {
111 /* Keep track of the maximum */
112 fdmax = newfd;
114 printf("New connection from %s:%d on socket %d\n",
115 inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);
117 } else {
118 /* An already connected master has sent a new query */
119 uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
121 rc = modbus_receive_from(ctx, master_socket, query);
122 if (rc != -1) {
123 modbus_reply(ctx, query, rc, mb_mapping);
124 } else {
125 /* Connection closed by the client, end of server */
126 printf("Connection closed on socket %d\n", master_socket);
127 close(master_socket);
129 /* Remove from reference set */
130 FD_CLR(master_socket, &refset);
132 if (master_socket == fdmax) {
133 fdmax--;
141 return 0;