tcpserver.c

/*
 * 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;
}
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 18 Mar 2016 for libqb by  doxygen 1.6.1