Página principal | Jerarquía de la clase | Lista alfabética | Lista de componentes | Lista de archivos | Miembros de las clases | Archivos de los miembros | Páginas relacionadas

jed_udp.C

Ir a la documentación de este archivo.
00001 //===========================================================================
00002 //= jed_udp.cc                                            Noviembre de 1998 =
00003 //=-------------------------------------------------------------------------=
00004 //= Definiciones portables para el uso de sockets en modo UDP.              =
00005 //=-------------------------------------------------------------------------=
00006 //= ADVERTENCIA: ESTE SOFTWARE NO ESTA CONCEBIDO NI DISENNADO PARA EL USO   =
00007 //= EN EQUIPO DE CONTROL EN LINEA EN ENTORNOS PELIGROSOS QUE REQUIERAN UN   =
00008 //= DESEMPENNO LIBRE DE FALLAS, COMO LA OPERACION DE PLANTAS NUCLEARES,     = 
00009 //= SISTEMAS DE NAVEGACION O COMUNICACION EN AVIONES, TRAFICO AEREO,        =
00010 //= EQUIPO MEDICO DEL CUAL DEPENDAN VIDAS HUMANAS O SISTEMAS DE ARMAMENTO,  =
00011 //= EN LOS CUALES UNA FALLA EN EL SOFTWARE PUEDA IMPLICAR DIRECTAMENTE LA   =
00012 //= MUERTE, DANNOS PERSONALES O DANNOS FISICOS Y/O AMBIENTALES GRAVES       =
00013 //= ("ACTIVIDADES DE ALGO RIESGO").                                         =
00014 //=-------------------------------------------------------------------------=
00015 //= Autor original: Oscar J. Chavarro G.  A.K.A. JEDILINK. Copyright (c),   =
00016 //= 1997 - 2003, oscarchavarro@hotmail.com                                  =
00017 //= AQUYNZA es software libre, y se rige bajo los terminos de la licencia   =
00018 //= LGPL de GNU (http://www.gnu.org). Para mayor informacion respecto a la  =
00019 //= licencia de uso, consulte el archivo ./doc/LICENCIA en la distribucion. =
00020 //===========================================================================
00021 
00022 #include "toolkits/net/jed_udp.h"
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #ifdef UNIX_ENABLED
00029     #include <strings.h>
00030 #endif
00031 
00032 #if (PLATAFORMA == i386_LINUX_GCC) || (PLATAFORMA == ALPHA) || (PLATAFORMA == SGI) || (PLATAFORMA == SUN) || (PLATAFORMA == SPARC64_LINUX_GCC)
00033     #include "toolkits/media/_unix_io.h"
00034 #endif
00035 
00036 #ifdef UNIX_ENABLED
00037 
00038 #define REPORTAR_ERROR_SOCKET()                                             \
00039     fprintf(stderr,                                                         \
00040         "<CONEXION_UDP> - ERROR: no puedo abrir un sockete datagrama.\n"    \
00041         "                 Motivo: ");                                       \
00042     switch ( errno ) {                                                      \
00043       case EPROTONOSUPPORT:                                                 \
00044         fprintf(stderr, "Protocolo TCP/IP no soportado!\n");                \
00045         break;                                                              \
00046       case EMFILE:                                                          \
00047         fprintf(stderr,                                                     \
00048             "Este proceso tiene demasiados archivos abiertos.\n");          \
00049         break;                                                              \
00050       case ENFILE:                                                          \
00051         fprintf(stderr,                                                     \
00052             "Existen demasiados archivos abiertos en el sistema!\n");       \
00053         break;                                                              \
00054       case EACCES:                                                          \
00055         fprintf(stderr, "Acceso denegado para abrir sockets en TCP/IP.\n"); \
00056         break;                                                              \
00057       case ENOBUFS:                                                         \
00058         fprintf(stderr, "Memoria insuficiente para abrir el socket!\n");    \
00059         break;                                                              \
00060       default:                                                              \
00061         fprintf(stderr, "desconocido (%d).\n", errno);                      \
00062         break;                                                              \
00063     }                                                                       \
00064     fflush(stderr);                                                         \
00065     return FALSE;
00066 
00067 #define REPORTAR_ERROR_BIND()                                               \
00068     fprintf(stderr,                                                         \
00069         "<CONEXION_UDP> - ERROR: no puedo agarrar un puerto local\n"        \
00070         "                 Motivo: ");                                       \
00071     switch ( errno ) {                                                      \
00072       case EBADF:                                                           \
00073         fprintf(stderr, "descriptor de socket invalido.\n");                \
00074         break;                                                              \
00075       case EINVAL: case EADDRINUSE:                                         \
00076         fprintf(stderr, "el puerto %d esta ocupado por otro proceso.\n",    \
00077             puerto_servidor);                                               \
00078         break;                                                              \
00079       case EACCES:                                                          \
00080         fprintf(stderr,"acceso denegado para este usuario tratando\n"       \
00081                        "                         de abrir el puerto %d.\n", \
00082             puerto_servidor);                                               \
00083         break;                                                              \
00084       case ENOTSOCK:                                                        \
00085         fprintf(stderr, "el descriptor de archivo no es un socket.\n");     \
00086         break;                                                              \
00087       default:                                                              \
00088         fprintf(stderr, "desconocido (%d).\n", errno);                      \
00089         break;                                                              \
00090     }                                                                       \
00091     fflush(stderr);                                                         \
00092     return FALSE;
00093 
00094 #endif
00095 
00096 #if PLATAFORMA == i386_WIN32_VC
00097 
00098     extern int WINSOCK_counter;
00099 
00100 
00101 #define REPORTAR_ERROR_SOCKET()                                             \
00102     fprintf(stderr,                                                         \
00103         "<CONEXION_UDP> - ERROR: no puedo abrir un sockete datagrama.\n");  \
00104     fflush(stderr);                                                         \
00105     return FALSE;
00106 
00107 #define REPORTAR_ERROR_BIND()                                               \
00108     fprintf(stderr,                                                         \
00109         "<CONEXION_UDP> - ERROR: no puedo agarrar un puerto local\n");      \
00110     fflush(stderr);                                                         \
00111     return FALSE;
00112 
00113 #endif
00114 
00115 
00116 //===========================================================================
00117 //= Clase CONEXION_UDP                                                      =
00118 //===========================================================================
00119 
00120 CONEXION_UDP::CONEXION_UDP(char *nombre, int puerto)
00121 {
00122     Nombre_servidor = new char[strlen(nombre) + 1];
00123 
00124     if ( !Nombre_servidor ) {
00125         fprintf(stderr, "<CONEXION_UDP> - ERROR: Memoria insuficiente!\n");
00126         fflush(stderr);
00127         exit(1);
00128     }
00129     
00130     strcpy(Nombre_servidor, nombre);
00131     puerto_servidor = puerto;
00132 #ifdef SOCKETS_ENABLED
00133     memset((char*)&extremo_remoto, 0, sizeof(extremo_remoto));
00134 #endif // SOCKETS_ENABLED
00135 }
00136 
00137 CONEXION_UDP::~CONEXION_UDP()
00138 {
00139     cerrar();
00140 }
00141 
00142 int
00143 CONEXION_UDP::id(void)
00144 {
00145     return _id;
00146 }
00147 
00148 void
00149 CONEXION_UDP::set_id(int i)
00150 {
00151     _id = i;
00152 }
00153 
00154 void
00155 CONEXION_UDP::cerrar(void)
00156 {
00157 #ifdef SOCKETS_ENABLED
00158   #ifdef UNIX_ENABLED
00159     close(sockfd);
00160   #endif
00161   #if PLATAFORMA == i386_WIN32_VC
00162     closesocket(sockfd);
00163     WINSOCK_counter--;
00164     if ( !WINSOCK_counter ) WSACleanup(); 
00165   #endif
00166 #endif // SOCKETS_ENABLED
00167 }
00168 
00169 BOOLEAN
00170 CONEXION_UDP::crear_como_servidor(void)
00176 {
00177 #ifndef SOCKETS_ENABLED
00178     fprintf(stderr,"<CONEXION_UDP> - ERROR: "
00179                    "No se ha compilado soporte para sockets UDP.\n"); 
00180     fflush(stderr);
00181     return FALSE;
00182 #endif
00183 
00184 #ifdef SOCKETS_ENABLED
00185   #if PLATAFORMA == i386_WIN32_VC
00186     int wcode;
00187     WORD wVersionRequested = MAKEWORD(1,1);
00188     WSADATA wsaData;
00189 
00190     if ( !WINSOCK_counter ) {
00191         wcode = WSAStartup(wVersionRequested, &wsaData);
00192         if ( wsaData.wVersion != wVersionRequested ) {   
00193             fprintf(stderr,
00194                 "<JED_UDP> - ERROR: Version incorrecta de Winsock!\n");
00195             fflush(stderr);
00196             return FALSE;
00197         }
00198     }
00199     WINSOCK_counter++;
00200   #endif
00201 
00202     //- Cree un socket (TCP/IP) no orientado a conexion (UDP) ---------------
00203     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00204   #ifdef UNIX_ENABLED
00205     if ( sockfd < 0 ) {
00206         REPORTAR_ERROR_SOCKET();
00207     }
00208   #endif
00209   #if PLATAFORMA == i386_WIN32_VC
00210     if( sockfd == INVALID_SOCKET ) {
00211         REPORTAR_ERROR_SOCKET();
00212     }
00213   #endif
00214 
00215     //- Ocupe el puerto IP/UDP designado ------------------------------------
00216     int code;
00217 
00218     //bzero((char*)&extremo_remoto, sizeof(extremo_remoto));
00219     memset((char*)&extremo_remoto, 0, sizeof(extremo_remoto));
00220     extremo_remoto.sin_family = AF_INET;
00221     extremo_remoto.sin_addr.s_addr = htonl(INADDR_ANY);
00222     extremo_remoto.sin_port = htons(puerto_servidor);
00223 
00224     code = bind( sockfd, 
00225                  (LPSOCKADDR)&extremo_remoto, 
00226                  sizeof(extremo_remoto) );
00227   #ifdef UNIX_ENABLED
00228     if ( code < 0 ) {
00229   #endif
00230   #if PLATAFORMA == i386_WIN32_VC
00231     if( code == SOCKET_ERROR ) {
00232   #endif
00233         REPORTAR_ERROR_BIND();
00234     }
00235 
00236     return TRUE;
00237 #endif // SOCKETS_ENABLED
00238 }
00239 
00240 BOOLEAN
00241 CONEXION_UDP::crear_como_cliente(void)
00245 {
00246 #ifndef SOCKETS_ENABLED
00247     fprintf(stderr,"<CONEXION_UDP> - ERROR: "
00248                    "No se ha compilado soporte para sockets UDP.\n"); 
00249     fflush(stderr);
00250     return FALSE;
00251 #endif
00252 
00253 #ifdef SOCKETS_ENABLED
00254   #if PLATAFORMA == i386_WIN32_VC
00255     int wcode;
00256     WORD wVersionRequested = MAKEWORD(1,1);
00257     WSADATA wsaData;
00258 
00259     if ( !WINSOCK_counter ) {
00260         wcode = WSAStartup(wVersionRequested, &wsaData);
00261         if ( wsaData.wVersion != wVersionRequested ) {   
00262             fprintf(stderr,
00263                 "<JED_UDP> - ERROR: Version incorrecta de Winsock!\n");
00264             fflush(stderr);
00265             return FALSE;
00266         }
00267     }
00268     WINSOCK_counter++;
00269   #endif
00270 
00271     //- Cree un socket (TCP/IP) no orientado a conexion (UDP) ---------------
00272     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00273     if ( sockfd < 0 ) {
00274         REPORTAR_ERROR_SOCKET();
00275     }
00276 
00277     //- Determine el servidor con el cual se conectara este socket ----------
00278     //bzero((void *)&extremo_remoto, (int)sizeof(extremo_remoto));
00279     memset((void *)&extremo_remoto, 0, (int)sizeof(extremo_remoto));
00280     extremo_remoto.sin_family = AF_INET;
00281     extremo_remoto.sin_addr.s_addr = inet_addr(Nombre_servidor);
00282     extremo_remoto.sin_port = htons(puerto_servidor);
00283 
00284     //- Ocupe un puerto cliente cualquiera ----------------------------------
00285     struct sockaddr_in cli_addr;
00286     int code;
00287 
00288     //bzero((void *)&cli_addr, (int)sizeof(cli_addr));
00289     memset((void *)&cli_addr, 0, (int)sizeof(cli_addr));
00290     cli_addr.sin_family = AF_INET;
00291     cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00292     cli_addr.sin_port = htons(0);
00293 
00294     code = bind(sockfd,
00295                 (LPSOCKADDR)&cli_addr, sizeof(cli_addr));
00296   #ifdef UNIX_ENABLED
00297     if ( code < 0 ) {
00298   #endif
00299   #if PLATAFORMA == i386_WIN32_VC
00300     if( code == SOCKET_ERROR ) {
00301   #endif
00302         REPORTAR_ERROR_BIND();
00303     }
00304 
00305     return TRUE;
00306 #endif // SOCKETS_ENABLED
00307 }
00308 
00309 int
00310 CONEXION_UDP::enviar(char *buffer, int tam_buffer)
00311 {
00312 #ifndef SOCKETS_ENABLED
00313     return -1;
00314 #endif
00315 
00316 #ifdef SOCKETS_ENABLED
00317     int i = sendto(sockfd, buffer, tam_buffer, 0,
00318                (const struct sockaddr *)(&(extremo_remoto)),
00319                sizeof(extremo_remoto));
00320 
00321 //    fflush(sockfd);
00322 
00323     return i;
00324 #endif // SOCKETS_ENABLED
00325 }
00326 
00327 int
00328 CONEXION_UDP::recibir(char *buffer, int tam_buffer)
00329 {
00330 #ifndef SOCKETS_ENABLED
00331     return -1;
00332 #endif
00333 
00334 #ifdef SOCKETS_ENABLED
00335     int clilen;
00336 
00337     clilen = sizeof(extremo_remoto);
00338 
00339     int r = recvfrom(sockfd, buffer, tam_buffer, 0, 
00340             (struct sockaddr *)(&(extremo_remoto)), (SOCK_INT *)&clilen);
00341 
00342 //    fflush(sockfd);
00343 
00344     return r;
00345 #endif // SOCKETS_ENABLED
00346 }
00347 
00348 
00349 #include <fcntl.h>
00350 
00351 #if PLATAFORMA == i386_WIN32_VC
00352 static void (*F)(void *, int);
00353 static void *Data;
00354 #endif
00355 
00356 void
00357 CONEXION_UDP::registro_asincronico(void (*f)(void *, int), void *User_data)
00358 {
00359 #ifdef SOCKETS_ENABLED
00360 
00361 //===========================================================================
00362 #if PLATAFORMA == i386_LINUX_GCC || PLATAFORMA == ALPHA || PLATAFORMA == SGI || PLATAFORMA == SUN || PLATAFORMA == SPARC64_LINUX_GCC
00363     instalar_sistema_asincronico();
00364     registrar_entrada(sockfd, f, User_data);
00365 #endif
00366 
00367 //===========================================================================
00368 
00369 #ifndef CBUILDER
00370 #if PLATAFORMA == i386_WIN32_VC
00371 // OJO: ESTO NUNCA A SIDO PROBADO!
00372     int code;
00373     HWND ventana_virtual;
00374 
00375     ventana_virtual = instalar_sistema_asincronico_sockets();
00376     registrar_entrada_sockets(sockfd, f, User_data);
00377 
00378     code = WSAAsyncSelect(sockfd, ventana_virtual,
00379         666 /* OJO: Este es el user-id */,
00380         FD_READ | FD_ACCEPT | FD_CLOSE
00381         /*| FD_WRITE | FD_OOB | FD_QOS | FD_GROUP_QOS | FD_CONNECT */
00382         );
00383 
00384     if ( code != 0 ) {
00385         fprintf(stderr, "<CONEXION_UDP> - ERROR: Fallo en WSAAsyncSelect.\n");
00386         fprintf(stderr, "WSAGetLastError = %d.\n", WSAGetLastError());
00387         fflush(stderr);
00388         exit(1);
00389     }
00390 
00391     //printf("<CONEXION_UDP> Registro funcion asincronica en fd %d\n", sockfd);
00392     //fflush(stdout);
00393 
00394     F = f;
00395     Data = User_data;
00396 #endif // i386_WIN32_VC
00397 #endif // CBUILDER
00398 //===========================================================================
00399   #ifdef DEBUG_UDP
00400     printf("<CONEXION_UDP> Registro funcion asincronica en fd %d\n", sockfd);
00401     fflush(stdout);
00402   #endif
00403 #endif // SOCKETS_ENABLED
00404 }
00405 
00406 //===========================================================================
00407 //= EOF                                                                     =
00408 //===========================================================================
00409 
00410 
00411 

Este archivo HTML ha sido generado automáticamente a partir del código fuente AQUYNZA. NO LO EDITE. Para mayor información contacte al autor.