[Idea] Librería para simplificar el uso de sockets

Iniciado por Miky Gonzalez, 19 Noviembre 2014, 19:15 PM

0 Miembros y 1 Visitante están viendo este tema.

Miky Gonzalez

Creo este tema para que aporten idea, una mejor solución o cualquier cosa que puedan aportar para mejorar esta pequeña idea.

En cuestión quiero crear una librería para simplificar el uso de sockets, en otra palabras, hacer las cosas más cómodamente.

La estructura general de la librería se compone de una estructura que almacena datos del socket; una estructura candidata posible podría ser algo como:

typedef int socket;

typedef struct libreria_socket {
socket socket_fd;
struct sockaddr_in host;
} socket;


La segunda cosa fundamental será la inicialización de esa estructura. Para ello necesitamos 2 funciones auxiliares que recibirán los parametros directamente desde una función principal iniciar_socket; la primera de ellas crear_socket, supongamos que AF (Adress Format) es INET (IP y puerto): AF_INET; la segunda de ellas podría tener 2 variantes: iniciar_sockaddr e iniciar_sockaddrany. La diferencia de estas es que en la estructura sockaddr_in, sin_addr atendería en todo el rango: 127.0.0.1/24.

Funciones secundarias, que bien podrían servir para formar parte de una función principal que automatice el proceso dependiendo de las necesidades del usuario final ó para tener el código más organizado, limpio, estético y hacer las cosas más sencillas. Estas son las funciones conectar_socket, bind_socket, escuchar_socket, aceptar_socket (esta según lo anterior también podría tener dos variantes: aceptar_socket y aceptar_socket_addrany), cerrar_socket.

Las funciones de lectura y escritura pueden usarse nativamente. Un pseudocódigo de cómo funcionaría la librería según las ideas que tengo ahora mismo:

socket socket_test;

iniciar_socket(&socket_test, 8080 /* puerto */, "127.0.0.1" /* direccion ip */);
conectar_socket(&socket_test);

char buffer[1024];

// Recibir datos
read(socket_test.socket_fd, buffer, 1024);

// Reenviar datos
write(socket_test.socket_fd, buffer, 1024);


De momento eso es todo. Aporten ideas, comentarios, soluciones, otra forma de hacerlo...

Saludos.
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

ivancea96

Si te sirve de apoyo, yo tengo esta estructura:

Código (cpp) [Seleccionar]
#ifndef SOCKETS_H
#define SOCKETS_H

#include <string>
#include <vector>
#include <windows.h>

using namespace std;

struct connection{
    SOCKET sock;
    string ip;

    connection():sock(INVALID_SOCKET){}
};

string recv(SOCKET s, size_t maxChars=1024);

bool send(SOCKET s, string msg);

void setBlocking(SOCKET sock, bool blocking);

class TCPRawServer{
    SOCKET _listener;
    unsigned short _port;
    bool _blocking;
    bool _on;

public:
    TCPRawServer();
    TCPRawServer(unsigned short port);
    ~TCPRawServer();
    bool start(unsigned short port);
    void finish();
    connection newClient();
    bool isOn()const;
    unsigned short getPort()const;
    void setBlocking(bool blocking);
    bool isBlocking()const;
};

class TCPServer:public TCPRawServer{
    struct _client{
        SOCKET socket;
        string ip;
        bool blocking;
        vector<string> data;

        _client():socket(INVALID_SOCKET),blocking(0){}
    };
    vector<_client> _clients;

public:
    TCPServer();
    TCPServer(unsigned short port);
    ~TCPServer();
    bool newClient();
    void disconnectClient(size_t clientN);
    string recv(size_t clientN, size_t maxChars=1024);
    bool send(size_t clientN, string msg);
    vector<string>* getData(size_t clientN);
    string getIp(size_t clientN)const;
    void setBlocking(size_t clientN, bool blocking);
    bool isBlocking(size_t clientN)const;
    size_t getClientCount()const;

};

class TCPClient{
    SOCKET _socket;
    string _ip;
    unsigned short _port;
    bool _connected;
    bool _blocking;

public:
    TCPClient();
    TCPClient(string ip, unsigned short port);
    ~TCPClient();
    bool connect(string ip, unsigned short port);
    void disconnect();
    string recv(int maxChars=1024);
    bool send(const string& msg);
    bool isConnected()const;
    string getIp()const;
    unsigned short getPort()const;
    void setBlocking(bool blocking);
    bool isBlocking()const;
};

#endif // SOCKETS_H


Más que nada para que veas las funcionalidades que tiene. Son las básicas.

Miky Gonzalez

Gracias por el aporte @ivancea96, claro que me sirve, aunque no uso C++, y la orienzación a objetos lo sustituyo por un struct que contenga la llamada a las funciones (intentando imitar programación con objetos, por ejemplo socket.conectar("127.0.0.1", 8080)), aunque estoy planteándome el uso de funciones predefinidas que obtengan como parámetro la estructura que contenga el socket y la estructura sockaddr_in.

Los principales motivos por el cual quiero usar funciones predefinidas es para ahorrarme crear una estructura que contenga 7 punteros que deben ser inicializados cada vez que cree una nueva estructura.

Publicaré el código cuando lo tenga como un aporte. Estoy puliendo crear una función, que no necesita explicación: create_server_single_addrany.

Saludos.
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN