src/network.c

Wed, 09 Apr 2014 12:07:47 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 09 Apr 2014 12:07:47 +0200
changeset 34
c4d4b8a8f902
parent 22
41bbfd4d17a3
child 45
e14a1d9aa91d
permissions
-rw-r--r--

added nonblocking read for network games + minor build system fixes

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2014 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    30 #include <stdlib.h>
    31 #include <string.h>
    32 #include <fcntl.h>
    33 #include "network.h"
    35 #define new_socket() socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    37 int net_create(Server *server, char* port) {
    38     server->info = NULL;
    40     struct sockaddr_in addr;
    41     addr.sin_family = AF_INET;
    42     addr.sin_addr.s_addr = INADDR_ANY;
    43     addr.sin_port = htons(atoi(port));
    45     server->fd = new_socket();
    46     if (server->fd > -1) {
    47         int true = 1;
    48         setsockopt(server->fd, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int));
    49         if (bind(server->fd, (struct sockaddr*)&addr, sizeof(addr))) {
    50             server->fd = -1;
    51             return 1;
    52         } else {
    53             return 0;
    54         }
    55     } else {
    56         return 1;
    57     }
    58 }
    60 int getaddrinfo_intrnl(char *host, char *port, struct addrinfo **info) {
    61     struct addrinfo hints;
    62     memset(&hints, 0, sizeof(hints));
    63     hints.ai_socktype = SOCK_STREAM;
    64     hints.ai_protocol = IPPROTO_TCP;
    66     return getaddrinfo(host, port, &hints, info);
    67 }
    69 int net_find(Server *server, char *host, char* port) {
    70     memset(server, 0, sizeof(Server));
    71     server->fd = -1;
    73     return getaddrinfo_intrnl(host, port, &(server->info));
    74 }
    76 int net_listen(Server *server) {
    77     listen(server->fd, 1);
    78     Client* client = calloc(1, sizeof(Client));
    79     client->fd = -1;
    80     server->client = client;
    82     client->fd = accept(server->fd,
    83         &(client->address), &(client->address_len));
    85     return client->fd == -1;
    86 }
    88 int net_connect(Server *server) {
    90     Client* client = calloc(1, sizeof(Client));
    91     client->fd = -1;
    92     server->fd = new_socket();
    93     server->client = client;
    95     if (server->fd == -1) {
    96         return 1;
    97     }
    99     return connect(server->fd, server->info->ai_addr, server->info->ai_addrlen);
   100 }
   102 int net_destroy(Server *server) {
   103     if (server->info) {
   104         freeaddrinfo(server->info);
   105     }
   106     if (server->client) {
   107         shutdown(server->client->fd, SHUT_RDWR);
   108         free(server->client);
   109     }
   110     if (server->fd > -1) {
   111         return shutdown(server->fd, SHUT_RDWR);
   112     }
   114     return EXIT_SUCCESS;
   115 }
   117 void net_send_code(int socket, uint8_t code) {
   118     send(socket, &code, sizeof(uint8_t), 0);
   119 }
   121 void net_send_data(int socket, uint8_t code, void *data, size_t len) {
   122     uint8_t pkg[len+1];
   123     pkg[0] = code;
   124     memcpy(pkg+1, data, len);
   125     send(socket, pkg, len+1, 0);
   126 }
   128 uint8_t net_recieve_code(int socket) {
   129     uint8_t code;
   130     recv(socket, &code, sizeof(uint8_t), 0);
   131     return code;
   132 }
   134 void net_recieve_data(int socket, void *data, size_t len) {
   135     recv(socket, data, len, 0);
   136 }
   138 int net_setnonblocking(int socket, _Bool nonblocking) {
   139     int opts = fcntl(socket, F_GETFL);
   140 	if (opts < 0) {
   141 		return 1;
   142 	}
   144     if (nonblocking) {
   145         opts |= O_NONBLOCK;
   146     } else {
   147         opts &= ~O_NONBLOCK;
   148     }
   149 	if (fcntl(socket, F_SETFL, opts) < 0) {
   150 		return 1;
   151 	}
   153     return 0;
   154 }

mercurial