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/>.
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
35 #define NB_CONNECTION 5
38 int server_socket
= -1;
39 modbus_mapping_t
*mb_mapping
;
41 static void close_sigint(int dummy
)
43 if (server_socket
!= -1) {
47 modbus_mapping_free(mb_mapping
);
54 uint8_t query
[MODBUS_TCP_MAX_ADU_LENGTH
];
59 /* Maximum file descriptor number */
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
));
73 server_socket
= modbus_tcp_listen(ctx
, NB_CONNECTION
);
75 signal(SIGINT
, close_sigint
);
77 /* Clear the reference set of socket */
79 /* Add the server socket */
80 FD_SET(server_socket
, &refset
);
82 /* Keep track of the max file descriptor */
83 fdmax
= server_socket
;
87 if (select(fdmax
+1, &rdset
, NULL
, NULL
, NULL
) == -1) {
88 perror("Server select() failure.");
92 /* Run through the existing connections looking for data to be
94 for (master_socket
= 0; master_socket
<= fdmax
; master_socket
++) {
96 if (!FD_ISSET(master_socket
, &rdset
)) {
100 if (master_socket
== server_socket
) {
101 /* A client is asking a new connection */
103 struct sockaddr_in clientaddr
;
106 /* Handle new connections */
107 addrlen
= sizeof(clientaddr
);
108 memset(&clientaddr
, 0, sizeof(clientaddr
));
109 newfd
= accept(server_socket
, (struct sockaddr
*)&clientaddr
, &addrlen
);
111 perror("Server accept() error");
113 FD_SET(newfd
, &refset
);
116 /* Keep track of the maximum */
119 printf("New connection from %s:%d on socket %d\n",
120 inet_ntoa(clientaddr
.sin_addr
), clientaddr
.sin_port
, newfd
);
123 modbus_set_socket(ctx
, master_socket
);
124 rc
= modbus_receive(ctx
, query
);
126 modbus_reply(ctx
, query
, rc
, mb_mapping
);
127 } else if (rc
== -1) {
128 /* This example server in ended on connection closing or
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
) {