⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp4u.c

📁 ISO 8583 with c++ for financial transaction standard
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Tcp4u v 3.30     Created may 93 - Last Revision 20/10/1997  3.20
 *
 *===========================================================================
 *
 * Project: Tcp4u,      Library for tcp protocol
 * File:    tcp4u.c
 * Purpose: main functions for tcp management
 *
 *===========================================================================
 *
 * This software is Copyright (c) 1996-1998 by Philippe Jounin
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *
 *
 *  If you make modifications to this software that you feel
 *  increases it usefulness for the rest of the community, please
 *  email the changes, enhancements, bug fixes as well as any and
 *  all ideas to me. This software is going to be maintained and
 *  enhanced as deemed necessary by the community.
 *
 *
 *             Philippe Jounin (ph.jounin@computer.org)
 */


#include "build.h"

#define TCP4U_SENDTIMEOUT   3600l  /* one hour */




/* ******************************************************************* */
/*                                                                     */
/* Partie I :  constructeurs /Destructeurs                             */
/*                                                                     */
/*                                                                     */
/*       Tcp4uInit, Tcp4uCleanup                                       */
/*                                                                     */
/*                                                                     */
/* ******************************************************************* */

/* ------------------------------------------------------------------ */
/* Initialisation                                                     */
/* ------------------------------------------------------------------ */
int API4U Tcp4uInit (void)
{
int     Rc=0;

   Tcp4uLog (LOG4U_PROC, "Tcp4uInit");

   Skt4uInit ();
#  ifdef _WINDOWS
   {
   /* enregistrement aupres de Winsock.Dll */
    WSADATA WSAData;
      Tcp4uLog (LOG4U_CALL, "WSAStartup, Winsock 1.1 required");
      Rc = WSAStartup (MAKEWORD (1,1), & WSAData);
   }
#  endif
   Tcp4uLog (LOG4U_EXIT, "Tcp4uInit");
return Rc==0 ? TCP4U_SUCCESS : TCP4U_ERROR;
} /* Tcp4uInit */



/* ------------------------------------------------------------------ */
/* Destructeurs                                                       */
/* ------------------------------------------------------------------ */
int API4U Tcp4uCleanup (void)
{
int Rc;
   Tcp4uLog (LOG4U_PROC, "Tcp4uCleanup");
   Rc = Skt4uCleanup ();
   Tcp4uLog (LOG4U_EXIT, "Tcp4uCleanup");
return Rc;
} /* Tcp4wCleanup */



/* ------------------------------------------------------------------ */
/* WINDOWS : Fin de vie de la DLL                                     */
/* ------------------------------------------------------------------ */
#ifdef TCP4W_DLL
int API4U WEP (int nExitType)
{
   Tcp4uLog (LOG4U_PROC, "WEP");
   Skt4uCleanup ();
   nExitType=0; /* suppress warning */
   Tcp4uLog (LOG4U_EXIT, "WEP");
return 1; /* definition Windows */
} /* WEP */
#endif



/* ------------------------------------------------------------------ */
/* Aliases : Tcp4uxInit/Tcp4uxCleanup ;  Tcp4wInit/Tcp4wCleanup       */
/* ------------------------------------------------------------------ */
#ifdef _WINDOWS
  int API4U Tcp4wInit (void)      { return Tcp4uInit ();    }
  int API4U Tcp4wCleanup (void)   { return Tcp4uCleanup (); }
#endif
#ifdef  UNIX
  int API4U Tcp4uxInit (void)     { return Tcp4uInit ();    }
  int API4U Tcp4uxCleanup (void)  { return Tcp4uCleanup (); }
#endif


/* ******************************************************************* */
/*                                                                     */
/* Partie I :  Fonctions de bas niveau TCP                             */
/*                                                                     */
/*                                                                     */
/*      TcpAbort                                                       */
/*      TcpAccept                                                      */
/*      TcpConnect                                                     */
/*      TcpClose                                                       */
/*      TcpFlush                                                       */
/*      TcpGetListenSocket                                             */
/*      TcpRecv                                                        */
/*      TcpSend                                                        */
/*                                                                     */
/* ******************************************************************* */



/* ------------------------------------------------------------ */
/* TcpAbort:  Stoppe un appel bloquant                          */
/*            Retourne TCP4U_SUCCESS                            */
/* ------------------------------------------------------------ */
int API4U TcpAbort (void)
{
   Tcp4uLog (LOG4U_PROC, "TcpAbort");
  if (WSAIsBlocking ())  
  {
     Tcp4uLog (LOG4U_CALL, "WSACancelBlockingCall");
     WSACancelBlockingCall ();
  }
  else      Tcp4uLog (LOG4U_ERROR, "TcpAbort: No calling process to cancel");
  Tcp4uLog (LOG4U_EXIT, "TcpAbort");
return TCP4U_SUCCESS;
} /* TcpAbort */



/* ------------------------------------------------------------ */
/* TcpAccept :  itablissement d'une connexion TCP avec Timeout  */
/*              Retourne TCP4U_ERROR, TCP4U_TIMEOUT, TCP4U_SUCCESS */
/*              ou TCP4U_BUFFERFREED si pConnectSock n'existe plus */
/*              En cas de succes la variable pConnectSock est   */
/*              renseignee.                                     */
/* ------------------------------------------------------------ */
int API4U TcpAccept (SOCKET far *pCSock, SOCKET ListenSock, UINT nTO)
{
struct timeval     TO;         /* Time Out structure    */
fd_set             ReadMask;   /* select mask           */
SOCKET             ConSock;
struct sockaddr_in saSockAddr; /* specifications pour le Accept */
struct linger      sling = { TRUE, 5 };    /* 5-seconds timeout */
int                nAddrLen = sizeof saSockAddr;
int                Rc;

  Tcp4uLog (LOG4U_PROC, "TcpAccept. Listen socket %d, Timeout %d", ListenSock, nTO);
  /* prepare select */
  FD_ZERO (& ReadMask);    /* mise a zero du masque */
  FD_SET (ListenSock, & ReadMask);  /* Attente d'evenement en lecture */
  TO.tv_sec = (long) nTO;  /* secondes */
  TO.tv_usec = 0;          /* microsecondes */
  /* s+1 normally unused but better for a lot of bugged TCP Stacks */
  Tcp4uLog (LOG4U_CALL, "select on socket %d", ListenSock);
  Rc = select (1+ListenSock, & ReadMask, NULL, NULL, nTO==0 ? NULL : & TO);
  if (Rc<0)   
  {
     Tcp4uLog (LOG4U_ERROR, "select on socket %d", ListenSock);
     return  IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR;  /* erreur reseau */
  }
  if (Rc==0)
  {
      Tcp4uLog (LOG4U_ERROR, "select on socket %d: Timeout", ListenSock);
      return  TCP4U_TIMEOUT;
  }

  Tcp4uLog (LOG4U_CALL, "accept on listen socket %d", ListenSock);
  ConSock = accept (ListenSock, (struct sockaddr far *) &saSockAddr, &nAddrLen);
  if (ConSock==INVALID_SOCKET)   
  {
     Tcp4uLog (LOG4U_ERROR, "accept on socket %d", ListenSock);
     return IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR;
  }
  Skt4uRcd (ConSock, STATE_SERVER);

  Tcp4uLog (LOG4U_CALL, "setsockopt SOL_LINGER on socket %d", ConSock);
  setsockopt (ConSock, SOL_SOCKET, SO_LINGER,(LPSTR) &sling, sizeof sling);
  /* validite des pointeurs */
  if (IsBadWritePtr (pCSock, sizeof *pCSock))
   {
     TcpClose (& ConSock);
     Tcp4uLog (LOG4U_ERROR, "TcpAccept. invalid pointer");
     return TCP4U_BUFFERFREED;
   }
  else
   {
      *pCSock = ConSock;
      Tcp4uLog (LOG4U_EXIT, "TcpAccept");
      return TCP4U_SUCCESS;
   }
} /* TcpAccept */



/* ------------------------------------------------------------ */
/* TcpClose - Fermeture d'une socket                            */
/*            La socket pointie par pS est fermie, *pS est      */
/*            mise ` INVALID_SOCKET.                            */
/*          - Retourne 1 en cas de succhs, -1 sinon (en giniral */
/*            du ` l'erreur WSAEINTR)                           */
/*            constantes (TCP4U_SUCCESS et TCP4U_ERROR)               */
/* ------------------------------------------------------------ */
int API4U TcpClose (SOCKET far *pS)
{
SOCKET s;
struct timeval     TO;         /* Time Out structure    */
struct S_HistoSocket *pStat;   /* stats about socket    */

  Tcp4uLog (LOG4U_PROC, "TcpClose socket %d", *pS);

  if (*pS==(unsigned) INVALID_SOCKET)  return TCP4U_SUCCESS; /* bien passe */
  s = *pS;
  pStat = Skt4uGetStats (s);
  if (pStat!=NULL  &&  pStat->nState==STATE_LISTEN)
    {
      /* Ici une petite tempo pour les winsockets qui n'apprecient */
      /* pas la succession trop rapide Accept/Close                */
     TO.tv_sec = 0;
     TO.tv_usec = 100000l;     /* microsecondes */
     select (s+1, NULL, NULL, NULL, & TO);
    } /* pause */

  /* Si on effectue un shutdown (s, 2), certaines winsocket */
  /* n'envoie plus la trame de longueur 0 caracteristique   */
  /* de la fin de connexion.                                */
  /* On le remplace donc par le TcpFlush                    */
  if (pStat!=NULL  &&  pStat->nState!=STATE_LISTEN)  TcpFlush (s);

  Tcp4uLog (LOG4U_CALL, "closesocket socket %d", s);
  if (CloseSocket (s)==0)
    {
       Skt4uUnRcd (s);
       if (!IsBadWritePtr(pS, sizeof *pS))  *pS =(unsigned) INVALID_SOCKET;
       else 			      				Tcp4uLog (LOG4U_ERROR, "TcpClose: Invalid pointer");

       Tcp4uLog (LOG4U_EXIT, "TcpClose");
       return TCP4U_SUCCESS;
    }
  Tcp4uLog (LOG4U_ERROR, "closesocket socket %d", s);

return TCP4U_ERROR;
} /* TcpClose */



/* --------------------------------------------------------------------- */
/* TcpConnect : Tentative d'etablissemnt d'une connexion TCP             */
/*              Retourne TCP4U_ERROR, TCP4U_SUCCESS, TCP4U_HOSTUNKNONW   */
/* --------------------------------------------------------------------- */
int API4U TcpConnect (SOCKET far *pS, LPCSTR szHost,
                      LPCSTR szService, unsigned short far *lpPort)
{
int                   Rc;
struct sockaddr_in    saSockAddr;
struct servent far *  lpServEnt;
SOCKET                connect_skt;
unsigned short        Zero = 0;

   Tcp4uLog (LOG4U_PROC, "TcpConnect. Host %s, service %s, port %u", 
             szHost, 
             szService==NULL ? "none" : szService, 
             lpPort==NULL ? -1 : *lpPort);

  *pS = INVALID_SOCKET;  /* par defaut erreur */
  if (lpPort==NULL)  lpPort = & Zero;  /* evite de tester sans arret */
  /* --- 1er champ de saSockAddr : Port */
  if (szService==NULL)  lpServEnt =  NULL ;
  else
  {
     Tcp4uLog (LOG4U_DBCALL, "getservbyname %s/tcp", szService);
     lpServEnt = getservbyname (szService, "tcp") ;
  }
  saSockAddr.sin_port = lpServEnt!=NULL ?   lpServEnt->s_port : htons(*lpPort);
  if (saSockAddr.sin_port == 0)  return TCP4U_BADPORT;  /* erreur dans port */
  /* --- 2eme champ de saSockAddr : Addresse serveur */
  saSockAddr.sin_addr = Tcp4uGetIPAddr (szHost);
  if (saSockAddr.sin_addr.s_addr==INADDR_NONE)   return TCP4U_HOSTUNKNOWN;
  /* --- Dernier champ : liaison connectie */
  saSockAddr.sin_family      = AF_INET; /* on utilise le mode connecte TCP */
  /* --- creation de la socket */
  Tcp4uLog (LOG4U_CALL, "socket PF_INET, SOCK_STREAM");
  if ( (connect_skt = socket (PF_INET, SOCK_STREAM, 0))==SOCKET_ERROR)
  {
       Tcp4uLog (LOG4U_ERROR, "socket");
       return  TCP4U_NOMORESOCKET;
  }
  /* --- connect retourne INVALID_SOCKET ou numero valide */
  Tcp4uLog (LOG4U_CALL, "connect on host %s", inet_ntoa (saSockAddr.sin_addr));
  Rc = connect (connect_skt,(struct sockaddr far *) & saSockAddr, sizeof saSockAddr);
  /* --- enregistrement dans notre table */
  if (Rc==SOCKET_ERROR)
  {
      Tcp4uLog (LOG4U_ERROR, "connect");
      CloseSocket (connect_skt);  /* release buffer */
  }
  else                   Skt4uRcd (connect_skt, STATE_CLIENT);
 *lpPort = htons (saSockAddr.sin_port);
  if (IsBadWritePtr (pS, sizeof *pS))  
  {
       Tcp4uLog (LOG4U_ERROR, "TcpConnect: invalid pointer");
       return TCP4U_BUFFERFREED;
   }
  else *pS = Rc==SOCKET_ERROR ? INVALID_SOCKET : connect_skt;
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -