Logo Search packages:      
Sourcecode: fenix-plugins version File versions  Download package

tcpsock.c

#include <fenix/fxdll.h>
#ifdef WIN32
#include <winsock.h>
#else

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#ifndef SOCKADDR
#define SOCKADDR struct sockaddr
#endif

#endif
#pragma pack()

/* PluginVersion is used to identify the plugin structures against which
 * we're linking to prevent potential mismatches and segmentation faults
 */
unsigned int PluginVersion = FXDLL_VERSION;

fd_set socketset[32];

// Inicializamos librería WinSock (version 2) - Devuelve 0 si no hubo error
static int tcpsock_init (INSTANCE * my, int * params)
{
#ifdef WIN32
      WSADATA wsaData;
      return (WSAStartup(MAKEWORD(2, 2),&wsaData));
#else
    return 0;
#endif
}

// Apaga la librería WinSock (devuelve 0 si fue correcto)
static int tcpsock_quit (INSTANCE * my, int * params)
{
#ifdef WIN32
      return (WSACleanup());
#else
    return 0;
#endif
}

// Devuelve la cantidad maxima de fds posibles de crear
static int tcpsock_getfdsetsize (INSTANCE * my, int * params)
{
      return FD_SETSIZE;
}

// Crea un socket TCP y lo devuelve (-1 es error)
static int tcpsock_open (INSTANCE * my, int * params)
{
      return (socket(AF_INET,SOCK_STREAM,0));
}

// Cierra un socket TCP (si fue correcto devuelve 0)
static int tcpsock_close (INSTANCE * my, int * params)
{
      shutdown(params[0],0);
#ifdef WIN32
      return (closesocket(params[0]));
#else
    return (close(params[0]));
#endif
}

// Asociamos el socket dado con el puerto especificado (si fue correcto devuelve 0)
static int tcpsock_bind (INSTANCE * my, int * params)
{
      struct sockaddr_in info_conexion;
      info_conexion.sin_family=AF_INET;
      info_conexion.sin_port=htons(params[1]);
      info_conexion.sin_addr.s_addr=INADDR_ANY;

      return (bind(params[0],(SOCKADDR*)&info_conexion,sizeof(info_conexion)));
}

// Fijamos el nº de peticiones que puede tener el socket anteriormente asociado (binded)
static int tcpsock_listen (INSTANCE * my, int * params)
{
      return (listen(params[0],params[1]));
}

// Acepta una petición de conexión del socket dado y devuelve su socket a usar
static int tcpsock_accept (INSTANCE * my, int * params)
{
      int socket;
      struct timeval timeout;
      fd_set readfds;
    struct sockaddr_in addr;
    int addrlen;

      FD_ZERO(&readfds);
      FD_SET(params[0], &readfds);
      timeout.tv_sec=0;
      timeout.tv_usec=0;

      if (select(FD_SETSIZE, &readfds, NULL, NULL, &timeout)>0) {
          addrlen=sizeof(addr);
          socket=accept(params[0], (struct sockaddr *)&addr, &addrlen);
          if(socket!=-1) {
              *(int *)params[1]=addr.sin_addr.s_addr ;
          }
      } else {
          socket=-1;
      }

      return socket;
}

// Realiza una petición de conexión a la dirección IP/Host y puerto dado
// con el socket dado determinado y devuelve 0 si fue correcto
static int tcpsock_connect (INSTANCE * my, int * params)
{
      char* ip=(char*)string_get(params[1]);
      struct sockaddr_in info_conexion;
      info_conexion.sin_family=AF_INET;
      info_conexion.sin_port=htons(params[2]);
      info_conexion.sin_addr.s_addr=inet_addr(ip);

      return (connect(params[0],(SOCKADDR*)&info_conexion,sizeof(info_conexion)));
}

// Realiza un select sobre el socket set indicado devolviendo
// el número de sockets que tienen actividad
static int tcpsock_select (INSTANCE * my, int * params)
{
      struct timeval timeout;

      timeout.tv_sec=params[1]/1000;
      timeout.tv_usec=params[1]%1000;

      return (select(FD_SETSIZE, &socketset[params[0]], NULL, NULL, &timeout));
}

// Envía un puntero de un tamaño determinado a través del socket dado
static int tcpsock_send (INSTANCE * my, int * params)
{
      char *envio=(char*)params[1];
      return (send(params[0],(void*)envio,params[2],0));
}

// Recibe un puntero de un tamaño determinado a través del socket dado
static int tcpsock_recv (INSTANCE * my, int * params)
{
      return (recv(params[0],(void*)params[1],params[2],0));
}

// Inicia o vacia el socket set indicado
static void tcpsock_fdzero (INSTANCE * my, int * params)
{
      FD_ZERO(&socketset[params[0]]);
}

// Añade un socket al socket set indicado
static int tcpsock_fdset (INSTANCE * my, int * params)
{
      FD_SET(params[1], &socketset[params[0]]);
#ifdef WIN32
      return socketset[params[0]].fd_count;
#else
      return FD_ISSET(params[1], &socketset[params[0]]);
#endif
}

// Elimina un socket del socket set indicado
static int tcpsock_fdclr (INSTANCE * my, int * params)
{
      FD_CLR(params[1], &socketset[params[0]]);
#ifdef WIN32
      return socketset[params[0]].fd_count;
#else
      return FD_ISSET(params[1], &socketset[params[0]]);
#endif
}

// Chequea si un socket tiene evento disponible
static int tcpsock_fdisset (INSTANCE * my, int * params)
{
      return (FD_ISSET(params[1], &socketset[params[0]]));
}

// Comprueba si hay actividad en el socket set indicado devolviendo
// el número de sockets que tienen actividad
static int tcpsock_socketset_check (INSTANCE * my, int * params)
{
      int check;
      fd_set temporal=socketset[params[0]];
      struct timeval timeout;

      timeout.tv_sec=0;
      timeout.tv_usec=0;

      check=select(FD_SETSIZE, &socketset[params[0]], NULL, NULL, &timeout);
      socketset[params[0]]=temporal;
      return check;
}

// Devuelve el nombre del host del PC o la dirección IP de la máquina
// que lo ejecuta según se especifique (0 o 1 respectivamente)
static int tcpsock_get_iphost (INSTANCE * my, int * params)
{
    int texto;
      char host[80];
      struct hostent *phe;
      struct in_addr addr;

      gethostname(host, sizeof(host));
      phe=gethostbyname(host);
    memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));

      if (!params[0])
      texto=string_new(host);
      else
      texto=string_new(inet_ntoa(addr)) ;

      string_use(texto) ;
      return texto;
}


FENIX_MainDLL RegisterFunctions (COMMON_PARAMS)
{
    FENIX_DLLImport

      FENIX_export ("TCPSOCK_INIT", "", TYPE_DWORD, tcpsock_init ) ;
      FENIX_export ("TCPSOCK_GETFDSETSIZE", "", TYPE_DWORD, tcpsock_getfdsetsize ) ;
      FENIX_export ("TCPSOCK_OPEN", "", TYPE_DWORD, tcpsock_open ) ;
      FENIX_export ("TCPSOCK_CLOSE", "I", TYPE_DWORD, tcpsock_close ) ;// Socket
      FENIX_export ("TCPSOCK_BIND", "II", TYPE_DWORD, tcpsock_bind ) ;// Socket, Puerto
      FENIX_export ("TCPSOCK_LISTEN", "II", TYPE_DWORD, tcpsock_listen ) ;// Socket, Nº de peticiones
      FENIX_export ("TCPSOCK_ACCEPT", "IP", TYPE_DWORD, tcpsock_accept ) ;// Socket, dword * ip
      FENIX_export ("TCPSOCK_CONNECT", "ISI", TYPE_DWORD, tcpsock_connect ) ;// Socket, IP/Host, Puerto
      FENIX_export ("TCPSOCK_SELECT", "II", TYPE_DWORD, tcpsock_select ) ; // Nº de SocketSet, Timeout (ms)
      FENIX_export ("TCPSOCK_SEND", "IPI", TYPE_DWORD, tcpsock_send ) ;// Socket, Puntero Dato, Tamaño
      FENIX_export ("TCPSOCK_RECV", "IPI", TYPE_DWORD, tcpsock_recv ) ;// Socket, Puntero Dato, Tamaño
      FENIX_export ("TCPSOCK_SOCKETSET_CHECK", "I", TYPE_DWORD, tcpsock_socketset_check ) ; // Nº de SocketSet
      FENIX_export ("TCPSOCK_SOCKETSET_FREE", "I", TYPE_DWORD, tcpsock_fdzero ) ;   // Nº de SocketSet
      FENIX_export ("TCPSOCK_SOCKETSET_ADD", "II", TYPE_DWORD, tcpsock_fdset ) ; // Nº de SocketSet, Socket
      FENIX_export ("TCPSOCK_SOCKETSET_DEL", "II", TYPE_DWORD, tcpsock_fdclr ) ; // Nº de SocketSet, Socket
      FENIX_export ("TCPSOCK_GET_IPHOST", "I", TYPE_STRING, tcpsock_get_iphost ) ; // Opción (0 Host, 1 IP)
      FENIX_export ("TCPSOCK_QUIT", "", TYPE_DWORD, tcpsock_quit ) ;
      FENIX_export ("TCPSOCK_FDZERO", "I", TYPE_DWORD, tcpsock_fdzero ) ;     // Nº de SocketSet
      FENIX_export ("TCPSOCK_FDSET", "II", TYPE_DWORD, tcpsock_fdset ) ; // Nº de SocketSet, Socket
      FENIX_export ("TCPSOCK_FDCLR", "II", TYPE_DWORD, tcpsock_fdclr ) ; // Nº de SocketSet, Socket
      FENIX_export ("TCPSOCK_FDISSET", "II", TYPE_DWORD, tcpsock_fdisset ) ; // Nº de SocketSet
}

Generated by  Doxygen 1.6.0   Back to index