1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*
* Copyright (c) 2011 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Angus Salkeld <asalkeld@redhat.com>
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif /* HAVE_NETDB_H */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif /* HAVE_SYS_POLL_H */
#include <qb/qbdefs.h>
#include <qb/qbloop.h>
static int32_t
sock_read_fn(int32_t fd, int32_t revents, void *data)
{
char recv_data[1024];
char send_data[1024];
int bytes_recieved;
if (revents & POLLHUP) {
printf("Socket %d peer closed\n", fd);
close(fd);
return QB_FALSE;
}
bytes_recieved = recv(fd, recv_data, 1024, 0);
if (bytes_recieved < 0) {
perror("recv");
return QB_TRUE;
}
recv_data[bytes_recieved] = '\0';
if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) {
printf("Quiting connection from socket %d\n", fd);
close(fd);
return QB_FALSE;
} else {
printf("Recieved: %s\n", recv_data);
snprintf(send_data, 1024, "ACK %d bytes", bytes_recieved);
if (send(fd, send_data, strlen(send_data), 0) < 0) {
close(fd);
return QB_FALSE;
}
}
return QB_TRUE;
}
static int32_t
sock_accept_fn(int32_t fd, int32_t revents, void *data)
{
struct sockaddr_in client_addr;
qb_loop_t *ml = (qb_loop_t *) data;
socklen_t sin_size = sizeof(struct sockaddr_in);
int connected = accept(fd, (struct sockaddr *)&client_addr, &sin_size);
if (connected < 0) {
perror("accept");
return QB_TRUE;
}
printf("I got a connection from (%s , %d)\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
qb_loop_poll_add(ml, QB_LOOP_MED, connected, POLLIN, ml, sock_read_fn);
return QB_TRUE;
}
static int32_t
please_exit_fn(int32_t rsignal, void *data)
{
qb_loop_t *ml = (qb_loop_t *) data;
printf("Shutting down at you request...\n");
qb_loop_stop(ml);
return QB_FALSE;
}
int
main(int argc, char *argv[])
{
int sock;
int true_opt = 1;
struct sockaddr_in server_addr;
qb_loop_t *ml = qb_loop_create();
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket");
exit(1);
}
if (setsockopt(sock,
SOL_SOCKET,
SO_REUSEADDR, &true_opt, sizeof(int)) == -1) {
perror("Setsockopt");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero), 8);
printf("TCPServer binding to port 5000\n");
if (bind(sock,
(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1) {
perror("Unable to bind");
exit(1);
}
printf("TCPServer Waiting for client on port 5000\n");
if (listen(sock, 5) == -1) {
perror("Listen");
exit(1);
}
qb_loop_poll_add(ml, QB_LOOP_MED, sock, POLLIN, ml, sock_accept_fn);
qb_loop_signal_add(ml, QB_LOOP_HIGH, SIGINT, ml, please_exit_fn, NULL);
qb_loop_run(ml);
close(sock);
return 0;
}
|