utiles_v2017/str_socket.cpp

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;
}
//**********************************************************************************************************************************