1
\$\begingroup\$

This is a lib I am doing to interact with sockets. :)

Here is the main file:

#include "net_socket.h"
#include <conio.h>

void command_line(B32 c, B8 ** v, B8U ** host, B32U * port);

int main(int argc, char** argv) {
    B8U * host = NULL;
    B32U port = 50;
    command_line(argc, argv, &host, &port);
    NET_SOCK server = net_sock_std(NULL, port);
    if (server.open(&server)) {
        if (!server.lock(&server, Off)) {printf("server socket locked\n");}
        if (!host) {
            NET_SOCK client = net_sock_std("localhost", port);
            printf("server openned in %hu\n", server.to.sin_port);
            if (client.open(&client)) {
                printf("Server client openned in %hu", client.to.sin_port);
            }

            if (server.tie(&server) && server.wait(&server, 1)) {
                printf("\nready\n");
            }
            while (!_kbhit()) { // I can't get in search mode
                printf("waiting\n");
                if(server.join(&server, &client))printf("server connected to client\n");
            }
            printf("end\n");
            client.pop(&client);

        } else {
            NET_SOCK client = net_sock_std(host, port);
            if (client.open(&client)) {
                printf("client openned in %s %hu\n", host, client.to.sin_port);
                while (!_kbhit()) {
                    if(client.in(&client))printf("client connected to server\n");
                }
            }
        }
        server.close(&server);
    }
    server.pop(&server);
    return (EXIT_SUCCESS);
}

void command_line(B32 c, B8 ** v, B8U ** host, B32U * port) {
    B32 i = 1;
    while (i < c) {
        switch (i) {
        case 1:
        {
            *port = atoi(v[i]);
        }
            break;
        case 2:
        {
            *host = v[i];
        }
            break;
        }
        i++;
    }
}

Here it is the source file:

#include "net_socket.h"

void net_sock_function(NET_SOCK * net) {
    if (net) {
        net->open = net_sock_open;
        net->lock = net_lock_socket;
        net->tie = net_sock_tie;
        net->wait = net_sock_wait;
        net->join = net_sock_join;
        net->in = net_sock_in;
        net->close = net_sock_close;
        net->pop = net_sock_pop;
    }
}

NET_SOCK net_sock_std(B8U * host, B32U port) {
    NET_SOCK net;
    net_sock_zero(&net);
    if (host) {
        net.host = strdup(host);
        if (strsub(net.host, ".")) {
            net.to.sin_addr.s_addr = inet_addr(net.host);
        } else {
            net.to.sin_addr.s_addr = inet_addr(net.name_to_ip(net.host));
        }
        //printf("host %s std\n",net.host);
    }
    if (port)net.to.sin_port = htons((u_short) port);
    bit_off(&net.status, NET_SOCK_ALLOCATED);
    return (net);
}

NET_SOCK * net_sock_push(B8U * host, B32U port) {
    NET_SOCK * net = malloc(sizeof (NET_SOCK));
    net_sock_zero(net);
    if (host) {
        net->host = strdup(host);
        if (strsub(net->host, ".")) {
            net->to.sin_addr.s_addr = inet_addr(net->host);
        } else {
            net->to.sin_addr.s_addr = inet_addr(net->name_to_ip(net->host));
        }
    }
    if (port)net->to.sin_port = htons((u_short) port);
    bit_on(&net->status, NET_SOCK_ALLOCATED);
    return (net);
}

void net_sock_zero(NET_SOCK * net) {
    if (net) {
        winsock_start();
        net->from.data = SOCK_STREAM;
        net->from.mode = IPPROTO_TCP;
        if (is_win()) {
            net->from.sys = AF_INET;
            net->to.sin_family = AF_INET;
        } else {
            net->from.sys = AF_UNIX;
            net->to.sin_family = AF_UNIX;
        }
        net->sock = -1;
        net->host = NULL;
        net->to.sin_addr.s_addr = htonl(INADDR_ANY);
        net->to.sin_port = 0;
        net_sock_function(net);
    }
}

STATUS net_sock_open(NET_SOCK * net) {
    if (!net)return (Off);
    if ((net->sock = socket(net->from.sys, net->from.data, net->from.mode)) != -1)return (On);
    return (Off);
}

STATUS net_sock_tie(NET_SOCK * server) {
    if (!server)return (Off);
    if (bind(server->sock, (NET_ADDR*) & server->to, sizeof (server->to)) != -1)return (On);
    return (Off);
}

STATUS net_sock_wait(NET_SOCK * net, B32 max) {
    if (!net)return (Off);
    if (listen(net->sock, max) != -1)return (On);
    return (Off);
}

STATUS net_sock_join(NET_SOCK * server, NET_SOCK * client) {
    if (!server || !client)return (Off);
    B32U clientLen = sizeof (client->to);
    if ((client->sock = accept(server->sock, (NET_ADDR *) & client->to, &clientLen)) != -1)return (On);
    return (Off);
}

STATUS net_sock_in(NET_SOCK * client) {
    if (!client)return (Off);
    if (connect(client->sock, (NET_ADDR *) & client->to, sizeof (client->to)) != -1)return (On);
    return (Off);
}

STATUS net_sock_put(NET_SOCK * net) {
    if (!net)return (Off);

    return (Off);
}

void net_sock_close(NET_SOCK * net) {
    if (is_win())closesocket(net->sock);
    else close(net->sock);
}

void net_sock_pop(NET_SOCK * net) {
    if (net) {
        if (net->host) {
            free(net->host);
            net->host = NULL;
        }
        if (bit_is_on(net->status, NET_SOCK_ALLOCATED)) {
            free(net);
            net = NULL;
        }
    }
}

void winsock_start() {
    if (is_win()) {
        WORD versionWanted = MAKEWORD(1, 1);
        WSADATA wsaData;
        WSAStartup(versionWanted, &wsaData);
        atexit(winsock_stop);
    }
}

B8U * net_sock_name_to_ip(B8U * host) {
    if (host) {
        struct hostent *h_ip = NULL;
        if ((h_ip = gethostbyname(host)) != NULL) {
            struct in_addr **addr = (struct in_addr **) h_ip->h_addr_list;
            B32 i = 0;
            while (addr[i] != NULL) {

                return (inet_ntoa(*addr[i]));
                i++;
            }
        }
    }
    return (NULL);
}

void winsock_stop() {
    if (is_win()) {
        WSACleanup();
    }
}

#include <fcntl.h>

STATUS net_lock_socket(NET_SOCK * net, STATUS block) {
    if (!net || net->sock < 0) return Off;
#if defined(WIN32)
        unsigned long mode = block ? 0 : 1;
        return (ioctlsocket(net->sock, FIONBIO, &mode) == 0) ? On : Off;
#else
        int flags = fcntl(net->sock, F_GETFL, 0);
        if (flags == -1) return Off;
        flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
        return (fcntl(net->sock, F_SETFL, flags) == 0) ? On : Off;
#endif
}

And finally the header:

#ifndef NET_SOCKET_H
#define NET_SOCKET_H

#ifdef __cplusplus
extern "C" {
#endif

#if defined(WIN32) || defined(WINDOWS_XP)
#include <winsock2.h>
#endif

#include <type-of/include/type.h>
#include <unistd.h>

#define NET_SOCK_ALLOCATED 1

    typedef struct NetSocket NET_SOCK;
    typedef struct sockaddr_in NET_ADDR_IN;
    typedef struct sockaddr NET_ADDR;

    struct NetSocket {

        struct {
            B32 sys; // PF_INET or PF_UNIX
            B32 data; // SOCK_STREAM or SOCK_DGRAM
            B32 mode; // IPPROTO_TCP or IPPROTO_UDP
        } from;
#if defined(WIN32) || defined(WINDOWS_XP)
        SOCKET sock;
#else
        B32 sock;
#endif
        B8 * host;
        NET_ADDR_IN to;
        BIT status;
        STATUS(*open)(NET_SOCK * net);
        STATUS(*lock)(NET_SOCK * net, STATUS block);
        STATUS(*tie)(NET_SOCK * server);
        STATUS(*wait)(NET_SOCK * net, B32 max);
        STATUS(*join)(NET_SOCK * server, NET_SOCK * client);
        STATUS(*in)(NET_SOCK * client);
        void (*close)(NET_SOCK * net);
        void (*pop)(NET_SOCK * net);
    };

    STATUS net_lock_socket(NET_SOCK * net, STATUS block);
    NET_SOCK net_sock_std(B8U * host, B32U port);
    NET_SOCK * net_sock_push(B8U * host, B32U port);
    void net_sock_zero(NET_SOCK * net);
    STATUS net_sock_open(NET_SOCK * net);
    STATUS net_sock_tie(NET_SOCK * server);
    STATUS net_sock_wait(NET_SOCK * net, B32 max);
    STATUS net_sock_join(NET_SOCK * server, NET_SOCK * client);
    STATUS net_sock_in(NET_SOCK * client);
    STATUS net_sock_put(NET_SOCK * net);
    void net_sock_close(NET_SOCK * net);
    void net_sock_pop(NET_SOCK * net);

    void winsock_start();
    void winsock_stop();


#ifdef __cplusplus
}
#endif

#endif /* NET_SOCKET_H */

Here is what I did in order not to get those mistakes anymore:

NET_SOCK net_sock_std(B8U * host, B32U port) {
    NET_SOCK net;
    net_sock_zero(&net);
    if (host){
        net.host = strdup(host);
        if(strsub(net.host,".")){
            net.to.sin_addr.s_addr = inet_addr(net.host);
        }
        else {
            net.to.sin_addr.s_addr = inet_addr(net.name_to_ip(net.host));
        }
        //printf("host %s std\n",net.host);
    }
    if (port)net.to.sin_port = htons((u_short)port);
    bit_off(&net.status, NET_SOCK_ALLOCATED);
    return (net);
}

NET_SOCK * net_sock_push(B8U * host, B32U port) {
    NET_SOCK * net = malloc(sizeof (NET_SOCK));
    net_sock_zero(net);
    if (host){
        net->host = strdup(host);
        if(strsub(net->host,".")){
            net->to.sin_addr.s_addr = inet_addr(net->host);
        }
        else {
            net->to.sin_addr.s_addr = inet_addr(net->name_to_ip(net->host));
        }
    }
    if (port)net->to.sin_port = htons((u_short)port);
    bit_on(&net->status, NET_SOCK_ALLOCATED);
    return (net);
}

B8U * net_sock_name_to_ip(B8U * host) {
    if (host) {
        struct hostent *h_ip = NULL;
        if ((h_ip = gethostbyname(host)) != NULL) {
            struct in_addr **addr = (struct in_addr **) h_ip->h_addr_list;
            B32 i = 0;
            while (addr[i] != NULL) {
                return (inet_ntoa(*addr[i]));
                i++;
            }
        }
    }
    return (NULL);
}

Here is how I define is_win:

#if (defined(WIN32) || defined(WINDOWS_XP))
#define is_win()(On)
#else // if not WIN32
#define is_win()(Off)
#endif // WIN32
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in fixing or changing what your code does. Once the code does what you want, we would love to help you do the same thing in a cleaner way! Please see our help center for more information. \$\endgroup\$ – Zeta Mar 21 '18 at 5:33
  • \$\begingroup\$ It is working. Just not as expected. \$\endgroup\$ – Lísias de Castro Mar 21 '18 at 5:35
  • \$\begingroup\$ "Not working as expected" sounds suspiciously like "not working." Questions about how to fix unexpected behavior really shod go on Stack Overflow instead. \$\endgroup\$ – EJoshuaS Mar 21 '18 at 5:43
  • \$\begingroup\$ It is working. I said. It was just a little detail. :) \$\endgroup\$ – Lísias de Castro Mar 21 '18 at 5:45
  • \$\begingroup\$ You should give us some credit sometimes. I knew it was a little detail to fix. \$\endgroup\$ – Lísias de Castro Mar 21 '18 at 6:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.