00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
00216 int code;
00217
00218
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
00272 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00273 if ( sockfd < 0 ) {
00274 REPORTAR_ERROR_SOCKET();
00275 }
00276
00277
00278
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
00285 struct sockaddr_in cli_addr;
00286 int code;
00287
00288
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
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
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
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 ,
00380 FD_READ | FD_ACCEPT | FD_CLOSE
00381
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
00392
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
00408
00409
00410
00411