481 lines
12 KiB
C++
481 lines
12 KiB
C++
#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(incre<MIN_REALLOC_STR_SOC)
|
|
incre=MIN_REALLOC_STR_SOC;
|
|
m+=incre;
|
|
aux=realloc(buf,m);
|
|
if(!aux)
|
|
{
|
|
m-=incre;
|
|
return FALSE;
|
|
}
|
|
buf=(char*)aux;
|
|
memset(&buf[m-incre],0,incre);
|
|
return TRUE;
|
|
}
|
|
//**********************************************************************************************************************************
|
|
void Cstr_socket::cierra()
|
|
{
|
|
pirate=TRUE;
|
|
while(cli_currando)
|
|
Sleep(1);
|
|
Close();
|
|
}
|
|
//**********************************************************************************************************************************
|
|
char * Cstr_socket::getbuf()
|
|
{
|
|
if(n>0)
|
|
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;
|
|
}
|
|
//**********************************************************************************************************************************
|