#include "StdAfx.h" #include "str_socket.h" #include "lock.h" #include "utiles_dll.h" //********************************************************************************************************************************** Cstr_socket::Cstr_socket(void) { buf=NULL; n=m=0; pirate=FALSE; nb=0; cli_currando=0; pp=NULL; } //********************************************************************************************************************************** Cstr_socket::~Cstr_socket(void) { cierra(); if(buf) free(buf); } //********************************************************************************************************************************** BOOL Cstr_socket::crear( char *ip/*=NULL*/, int puerto/*=0*/ ) { Cutiles_dll dll; pirate=FALSE; BOOL resul = CAsyncSocket::Create(puerto, SOCK_STREAM,FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, ip); if (!resul) er.pon_win("Cstr_socket"); return resul; } //********************************************************************************************************************************** BOOL Cstr_socket::conecta( char *ip, int puerto ) { fd_set rfds; struct timeval tv; FD_ZERO(&rfds); char log_error[512]; FD_SET(this->m_hSocket, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; int err,vez; if (!Connect(ip, puerto)) { err = GetLastError(); if(err != WSAEWOULDBLOCK) { er.pon_win("Cstr_socket"); return(FALSE); } } // ahora espera hasta que esté conectado vez = 0; do { int pruebaconexion = select(this->m_hSocket+1, NULL, &rfds, NULL, &tv); if(pruebaconexion == 1) break; else if(pruebaconexion == SOCKET_ERROR) err=WSAGetLastError(); vez++; Sleep(100); if (vez > 50) // 5 segundos { sprintf(log_error,"No puede conectar a IP %s %ld. Demasiado tiempo para conectar",ip, puerto); er.pon("Cstr_socket",log_error,-1); return(FALSE); } } while (!pirate); if(pirate) { er.pon("Cstr_socket","Error en conectar, pirate es true",-1); return FALSE; } return(TRUE); } //********************************************************************************************************************************** char* Cstr_socket::recibir() { int nbb,k; n=0; //recibe numero de caracteres---------------------------- nbb=recibir((BYTE*)&k,sizeof(int)); if(nbb<0) return NULL; if(!nbb) { if(!cuida_mem(1)) return NULL; buf[0]=0; n=1; return buf; } if(k<=0) { er.pon("Cstr_socket", "Bloque defectuoso: número de caracteres 0 o negata"); return NULL; } if(!cuida_mem(k+1)) return NULL; nb=k; n=0; while(k>0) { /*char st[128]; sprintf(st,"quedan %ld, k=%ld\n",min(k,MAX_CHAR_BLOQ_STRSOCKET), k); TRACE(st);*/ nbb=recibir((BYTE*)&buf[n],min(k,MAX_CHAR_BLOQ_STRSOCKET)); if(nbb<=0)//devuelve lo que se tenga hasta ahora break; n+=nbb; k-=nbb; } buf[n]=0; n++; return buf; } //********************************************************************************************************************************** int Cstr_socket::recibir( BYTE *b, int nbb ) { int ini=0,k=0; int veces=0; do { k = Receive(&b[ini],nbb-ini); if(k<0) { //e = GetLastError(); if(GetLastError() != WSAEWOULDBLOCK ) { er.pon_win("Cstr_socket"); return -1; } } else if(k>0) { veces=0; ini+=k; if(ini>=nbb) return ini; continue; } else { k=GetLastError(); if(k!=0) k=k; } veces++; if(veces>VECES_ESPERA_STRSOCKET) { er.pon("Cstr_socket","Error en recibir: superado el tiempo de espera",-1); return(ini); } Sleep(ESPERA_STRSOCKET); } while (!pirate); er.pon("Cstr_socket","Error en recibir: Procesos cancelados por usuario",-1); return(-1); } //********************************************************************************************************************************** BOOL Cstr_socket::envia( char *fmt, ... ) { n=0; if(!cuida_mem(MIN_REALLOC_STR_SOC)) return FALSE; int k; va_list arg_ptr; va_start(arg_ptr, fmt); do { k = _vsnprintf(buf,m, fmt, arg_ptr); if(k<0) { n+=MIN_REALLOC_STR_SOC; if(!cuida_mem(MIN_REALLOC_STR_SOC)) break; } } while (k<0); va_end(arg_ptr); if(k<0) return FALSE; n=strlen(buf); k=0; //envia numero de caracteres------------ if(!enviar((int)sizeof(int),(BYTE*)&n)) return FALSE; while(n>0) { /*char st[512]; sprintf(st,"Envio %ld, n=%ld\n",min(n,MAX_CHAR_BLOQ_STRSOCKET), n); TRACE(st);*/ if(!enviar( min(n, MAX_CHAR_BLOQ_STRSOCKET), (BYTE*)&buf[k])) return FALSE; n-=MAX_CHAR_BLOQ_STRSOCKET; k+=MAX_CHAR_BLOQ_STRSOCKET; } n=0; return TRUE; } //********************************************************************************************************************************** BOOL Cstr_socket::enviar(int nbb,BYTE *b) { int ini=0, k, nv=0,e; int ns,ib; nv = ib = 0; // envía al servidor while (!pirate && nbb > 0) { k = Send(&b[ini],nbb,0); if (k > 0) { ini+=k; nbb-=k; nv = 0; // reset tiempo espera } else { e = GetLastError(); if (e == WSAENOTCONN) { ns = 0; if (nv > VECES_ESPERA_STRSOCKET) { er.pon("Cstr_socket","Error no conectado al enviar, superado el tiempo de espera",-1); return(FALSE); } } else if (e != WSAEWOULDBLOCK) { er.pon_win("Cstr_socket"); return(FALSE); } nv++; if (nv > (VECES_ESPERA_STRSOCKET)) { er.pon("Cstr_socket","Error al enviar, superardo el tiempo de espera",-1); return(FALSE); } Sleep(ESPERA_STRSOCKET); } } if(pirate) { er.pon("Cstr_socket","Error al enviar: procesos cancelados por usuario",-1); return FALSE; } return TRUE; } //********************************************************************************************************************************** BOOL Cstr_socket::cuida_mem( int nbb ) { void *aux; int incre=n+nbb-m; if(incre<=0) return TRUE; if(incre0) return buf; n=0; if(!cuida_mem(1)) return NULL; buf[0]=0; n=1; return buf; } //********************************************************************************************************************************** void Cstr_socket_srv::OnAccept(int nErrorCode) { int k; SOCKADDR so; if(pirate) goto salir; Cstr_socket_srv* cli=NULL; cli=crea_cliente(); cli->id_even=id_even; cli->id_comman=id_comman; cli->sal_soc=&pirate; cli->wnd=wnd; cli->t_out=t_out; if (!cli) goto salir; k = sizeof(SOCKADDR); if (!Accept( *cli, &so,&k)) { delete cli; goto salir; } lck_sum_atm(&cli_currando,1); cli->pp=this; // crea thread para atender la consulta AfxBeginThread(Cstr_socket_srv::th_funcion, (LPVOID)cli, THREAD_PRIORITY_NORMAL, 0, 0, NULL); salir: Cstr_socket::OnAccept(nErrorCode); } //********************************************************************************************************************************** void Cstr_socket_srv::run() { t=_time64(NULL); char *st; Sleep(100); while(!*sal_soc && !pirate) { st=recibir(); if(!st) { pirate=TRUE; continue; } if(!st[0]) { if((_time64(NULL)-t)>t_out) { pirate=TRUE; continue; } } else { t=_time64(NULL); pirate=!on_datos_recibidos(st); continue; } Sleep(10); } if(pp) (&pp->cli_currando,-1); if(wnd) PostMessage(wnd,id_comman,(WPARAM)id_even,(LPARAM)this);//para salir y destruir el socket } //********************************************************************************************************************************** UINT Cstr_socket_srv::th_funcion( LPVOID pp ) { ((Cstr_socket_srv*)pp)->run(); return 0; } //********************************************************************************************************************************** BOOL Cstr_socket_srv::pon_escucha( char *ip, int puerto ) { if(!crear(ip,puerto)) return FALSE; if(!Listen()) { er.pon_win("Cstr_socket_srv"); return FALSE; } return TRUE; } //********************************************************************************************************************************** void Cstr_socket_srv::OnClose( int nErrorCode ) { pirate=TRUE; Cstr_socket::OnClose(nErrorCode); } //********************************************************************************************************************************** Cstr_socket_srv::Cstr_socket_srv( void ) { wnd=NULL; id_even=0; sal_soc=NULL; t_out=60; t=0; } //********************************************************************************************************************************** Cstr_socket_srv::~Cstr_socket_srv( void ) { } //********************************************************************************************************************************** void Cstr_socket_srv::pon_wnd_destruc( HWND wnd,int id_comman,int id_even ) { this->wnd=wnd; this->id_comman=id_comman; this->id_even=id_even; } //********************************************************************************************************************************** void Cstr_socket_srv::pon_tout( int t_out ) { this->t_out = t_out; } //********************************************************************************************************************************** //********************************************************************************************************************************** extern "C" UTILES_EXPORT BOOL str_socket_conecta( Cstr_socket *soc, char *ip, int puerto ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return soc->crear() && soc->conecta(ip, puerto); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT Cstr_socket * str_socket_crea() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return new Cstr_socket(); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT BOOL str_socket_envia( Cstr_socket *soc, char *txt ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return soc->envia(txt); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT int str_socket_recive( Cstr_socket* soc ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); char *st=soc->recibir(); if(!st) return -1; else return strlen(st); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT void str_socket_dame_buf( Cstr_socket* soc, char* buf ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); char *st; st=soc->getbuf(); if(!st) strcpy(buf,""); else strcpy(buf,st); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT void str_socket_dame_error( Cstr_socket* soc, char* error ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); sprintf(error,"Mod: %s, desc:%s", soc->er.modulo,soc->er.msg); } //********************************************************************************************************************************** extern "C" UTILES_EXPORT void str_socket_borra( Cstr_socket* soc ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); delete soc; } //**********************************************************************************************************************************