📄 tcp4u.c
字号:
Tcp4uLog (LOG4U_EXIT, "TcpConnect");
return Rc==SOCKET_ERROR ? TCP4U_CONNECTFAILED : TCP4U_SUCCESS;
} /* TcpConnect */
/* ------------------------------------------------------------ */
/* TcpFlush: Vide le buffer relatif a une socket */
/* Retourne TCP4U_ERROR, TCP4U_SUCCESS, TCP4U_CLOSEDSOCKET */
/* ------------------------------------------------------------ */
int API4U TcpFlush (SOCKET s)
{
int nBR=-1;
char szBuf[64];
Tcp4uLog (LOG4U_PROC, "TcpFlush on socket %d", s);
if (s==INVALID_SOCKET) return TCP4U_ERROR;
while ( TcpIsDataAvail (s) && (nBR=recv (s,szBuf,sizeof szBuf,0)) > 0 )
Tcp4uDump (szBuf, nBR, "Flushed");
while ( TcpIsOOBDataAvail (s) &&(nBR=recv (s,szBuf,sizeof szBuf,MSG_OOB))>0 )
Tcp4uDump (szBuf, nBR, "Flushed");
Tcp4uLog (LOG4U_EXIT, "TcpFlush");
if (nBR<0) return IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR;
if (nBR==0) return TCP4U_SOCKETCLOSED;
return TCP4U_SUCCESS;
} /* TcpFlush */
/* ------------------------------------------------------------ */
/* TcpGetListenSocket */
/* Retourne TCP4U_ERROR, TCP4U_SUCCESS */
/* ------------------------------------------------------------ */
int API4U TcpGetListenSocket (SOCKET far *pS, LPCSTR szService,
unsigned short far *lpPort, int nPendingConnection)
{
struct sockaddr_in saSockAddr; /* specifications pour le Accept */
int nAddrLen;
SOCKET ListenSock;
int One=1;
int Rc;
unsigned short Zero = 0;
struct servent far * lpServEnt;
Tcp4uLog (LOG4U_PROC, "TcpGetListenSocket on service %s, port %u",
szService==NULL ? "none" : szService,
lpPort==NULL ? 0 : *lpPort);
*pS = INVALID_SOCKET;
if (lpPort==NULL) lpPort = & Zero;
/* --- 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);
#ifdef CONTROL_EN_TROP
if (saSockAddr.sin_port==0) return TCP4U_BADPORT; /* erreur attribution Port */
#endif
/* create socket */
Tcp4uLog (LOG4U_CALL, "socket AF_INET, SOCK_STREAM");
ListenSock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSock==INVALID_SOCKET)
{
Tcp4uLog (LOG4U_ERROR, "socket");
return TCP4U_NOMORESOCKET;
}
saSockAddr.sin_family = AF_INET;
saSockAddr.sin_addr.s_addr=INADDR_ANY;
/* set options ReuseAddress and Linger */
Tcp4uLog (LOG4U_CALL, "setsockopt SO_REUSEADDR on sock %d", ListenSock);
setsockopt (ListenSock, SOL_SOCKET, SO_REUSEADDR, (char far *)&One, sizeof One);
Tcp4uLog (LOG4U_CALL, "setsockopt SO_LINGER on sock %d", ListenSock);
setsockopt (ListenSock, SOL_SOCKET, SO_LINGER,(char far *)&One, sizeof One);
/* Bind name to socket */
Tcp4uLog (LOG4U_CALL, "bind socket %d to %s", ListenSock, inet_ntoa (saSockAddr.sin_addr));
Rc = bind (ListenSock,(struct sockaddr far *) & saSockAddr, sizeof(struct sockaddr));
if (Rc != SOCKET_ERROR)
{
Tcp4uLog (LOG4U_CALL, "listen on socket %d. %d pendind connections", ListenSock, nPendingConnection);
Rc = listen (ListenSock, nPendingConnection);
}
if (Rc==SOCKET_ERROR)
{
Tcp4uLog (LOG4U_ERROR, "bind or listen on socket %d", WSAGetLastError (), ListenSock);
CloseSocket (ListenSock);
return TCP4U_BINDERROR;
}
/* Get port id with getsockname */
nAddrLen = sizeof saSockAddr;
memset (& saSockAddr, 0, sizeof(struct sockaddr) );
Tcp4uLog (LOG4U_DBCALL, "getsockname on socket %d", ListenSock);
getsockname (ListenSock, (struct sockaddr far *) &saSockAddr, &nAddrLen);
*lpPort = htons (saSockAddr.sin_port);
Skt4uRcd (ListenSock, STATE_LISTEN);
if (IsBadWritePtr (pS, sizeof *pS))
{
Tcp4uLog (LOG4U_ERROR, "TcpGetListenSocket: invalid pointer");
return TCP4U_BUFFERFREED;
}
else *pS = ListenSock;
Tcp4uLog (LOG4U_EXIT, "TcpGetListenSocket");
return TCP4U_SUCCESS;
} /* TcpGetListenSock */
/* ------------------------------------------------------------ */
/* TcpRecv - Lecture d'une trame avec Timeout */
/* TcpRecv recoit uBufSize octets de donnies */
/* la fonction s'arrjte avant si la socket est fermie */
/* ou si une timeout arrive. */
/* - Retourne le nombre d'octets lus, */
/* TCP4U_SOCKETCLOSED si la socket a iti fermie */
/* TCP4U_ERROR sur une erreur de lecture */
/* TCP4U_TIMEOUT sur un TO */
/* TCP4U_BUFFERFREED si libiration des buffers */
/* - Remarque : Pour iviter que le buffer appelant soit */
/* libere de manihre asynchrone, la fonction utilise */
/* ses propres buffers. */
/* - Ajout des modes TCP4U_WAITFOREVER et TCP4U_WAIT */
/* ------------------------------------------------------------ */
/* forme avec log */
int API4U TcpRecv (SOCKET s, LPSTR szBuf, unsigned uBufSize,
unsigned uTimeOut, HFILE hLogFile)
{
int Rc;
Tcp4uLog (LOG4U_PROC, "TcpRecv on socket %d. Timeout %d, bufsize %d", s, uTimeOut, uBufSize);
Rc = InternalTcpRecv (s, szBuf, uBufSize, uTimeOut, hLogFile);
if (Rc>=TCP4U_SUCCESS) Tcp4uDump (szBuf, Rc, DUMP4U_RCVD);
Tcp4uLog (LOG4U_EXIT, "TcpRecv");
return Rc;
} /* TcpRecv */
/* forme sans log */
int InternalTcpRecv (SOCKET s, LPSTR szBuf, unsigned uBufSize,
unsigned uTimeOut, HFILE hLogFile)
{
char cBuf;
LPSTR p = NULL;
int Rc, nUpRc; /* Return Code of select and recv */
struct timeval TO; /* Time Out structure */
struct timeval *pTO; /* Time Out structure */
fd_set ReadMask; /* select mask */
if (s==INVALID_SOCKET) return TCP4U_ERROR;
FD_ZERO (& ReadMask); /* mise a zero du masque */
FD_SET (s, & ReadMask); /* Attente d'evenement en lecture */
/* detail des modes */
switch (uTimeOut)
{
case TCP4U_WAITFOREVER : pTO = NULL;
break;
case TCP4U_DONTWAIT : TO.tv_sec = TO.tv_usec=0 ;
pTO = & TO;
break;
/* Otherwise uTimeout is really the Timeout */
default : TO.tv_sec = (long) uTimeOut;
TO.tv_usec=0;
pTO = & TO;
break;
}
/* s+1 normally unused but better for a lot of bugged TCP Stacks */
Tcp4uLog (LOG4U_CALL, "select on socket %d", s);
Rc = select (s+1, & ReadMask, NULL, NULL, pTO);
if (Rc<0)
{
Tcp4uLog (LOG4U_ERROR, "select on socket %d", s);
return IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR;
}
if (Rc==0)
{
Tcp4uLog (LOG4U_ERROR, "select on socket %d: Timeout", s);
return TCP4U_TIMEOUT; /* timeout en reception */
}
if (szBuf==NULL || uBufSize==0)
{
Tcp4uLog (LOG4U_EXIT, "TcpRecv");
return TCP4U_SUCCESS;
}
if (uBufSize==1) /* cas frequent : lecture caractere par caractere */
p = & cBuf;
else
{
p = Calloc (uBufSize, 1);
if (p==NULL) return TCP4U_INSMEMORY;
}
Tcp4uLog (LOG4U_CALL, "recv socket %d, buffer %d bytes", s, uBufSize);
Rc = recv (s, p, uBufSize, 0); /* chgt 11/01/95 */
switch (Rc)
{
case SOCKET_ERROR :
Tcp4uLog (LOG4U_ERROR, "recv socket %d", s);
nUpRc = IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR ;
break;
case 0 :
Tcp4uLog (LOG4U_ERROR,"socket %d: Host has closed connection", s);
nUpRc = TCP4U_SOCKETCLOSED ;
break;
default :
if (hLogFile!=HFILE_ERROR) Write (hLogFile, p, Rc);
if (IsBadWritePtr (szBuf, 1)) nUpRc = TCP4U_BUFFERFREED;
else memcpy (szBuf, p, nUpRc=Rc);
break;
} /* translation des codes d'erreurs */
if (p!=NULL && uBufSize!=1) Free (p);
return nUpRc;
} /* TcpRecv */
/* ------------------------------------------------------------ */
/* TcpSend : Envoi de uBufSize octets vers le distant */
/* Retourne TCP4U_ERROR ou TCP4U_SUCCESS */
/* ------------------------------------------------------------ */
/* forme avec log */
int API4U TcpSend (SOCKET s, LPCSTR szBuf, unsigned uBufSize,
BOOL bHighPriority, HFILE hLogFile)
{
int Rc;
Tcp4uLog (LOG4U_PROC,"TcpSend on socket %d. %d bytes to be sent",s,uBufSize);
Rc = InternalTcpSend (s, szBuf, uBufSize, bHighPriority, hLogFile);
if (Rc==TCP4U_SUCCESS) Tcp4uDump (szBuf, uBufSize, DUMP4U_SENT);
Tcp4uLog (LOG4U_EXIT, "TcpSend");
return Rc;
} /* TcpSend */
/* forme sans log */
int InternalTcpSend (SOCKET s, LPCSTR szBuf, unsigned uBufSize,
BOOL bHighPriority, HFILE hLogFile)
{
int Rc;
unsigned Total;
LPSTR p;
if (s==INVALID_SOCKET) return TCP4U_ERROR;
p = Calloc (uBufSize, 1);
if (p==NULL) return TCP4U_INSMEMORY;
memcpy (p, szBuf, uBufSize);
if (hLogFile!=HFILE_ERROR) Write (hLogFile, p, uBufSize);
for ( Total = 0, Rc = 1 ; Total < uBufSize && Rc > 0 ; Total += Rc)
{
Tcp4uLog (LOG4U_CALL, "send on socket %d. %d bytes to be sent",
s, uBufSize-Total);
Rc = send (s, & p[Total], uBufSize-Total, bHighPriority ? MSG_OOB : 0);
if (Rc<=0) Tcp4uLog (LOG4U_ERROR, "send on socket %d.", s);
}
Free(p);
return Total>=uBufSize ? TCP4U_SUCCESS : IsCancelled() ? TCP4U_CANCELLED : TCP4U_ERROR;
} /* TcpSend */
/* ******************************************************************* */
/* */
/* Partie I (suite) : Fonctions d'information */
/* */
/* TcpGetLocalID */
/* TcpGetRemoteID */
/* TcpIsDataAvail */
/* */
/* ******************************************************************* */
/* ------------------------------------------------------------ */
/* TcpGetLocalID: Retourne nom et adresse IP de la station */
/* Retourne TCP4U_SUCCESS, TCP4U_ERROR */
/* ------------------------------------------------------------ */
int API4U TcpGetLocalID (LPSTR szStrName, int uNameSize, DWORD far *lpAddress)
{
char szName[128];
struct hostent far *lpHostEnt;
int Rc;
Tcp4uLog (LOG4U_PROC, "TcpGetLocalID");
if (lpAddress!=NULL) memset (lpAddress, 0, sizeof (DWORD));
/* on envisage 2 methodes pour obtenir le nom du PC */
/* d'abord un appel a gethostname */
Tcp4uLog (LOG4U_DBCALL, "gethostname");
if (gethostname (szName, sizeof szName)==SOCKET_ERROR) return TCP4U_ERROR;
if (lpAddress != NULL)
{
Tcp4uLog (LOG4U_DBCALL, "gethostbyname on host %s", szName);
lpHostEnt = gethostbyname (szName);
if (lpHostEnt==NULL) return TCP4U_ERROR;
memcpy (lpAddress, lpHostEnt->h_addr_list[0], lpHostEnt->h_length);
}
if (szStrName!=NULL)
{
Strcpyn (szStrName, szName, uNameSize);
Rc = Strlen(szName)>Strlen(szStrName) ? TCP4U_OVERFLOW : TCP4U_SUCCESS;
}
else Rc = TCP4U_SUCCESS;
Tcp4uLog (LOG4U_EXIT, "TcpGetLocalID");
return TCP4U_SUCCESS;
} /* TcpGetLocalID */
/* ------------------------------------------------------------ */
/* TcpGetRemoteID: Retourne nom et adresse IP du distant */
/* Retourne TCP4U_SUCCESS, TCP4U_ERROR */
/* ------------------------------------------------------------ */
int API4U TcpGetRemoteID (SOCKET s, LPSTR szStrName, int uNameSize,
DWORD far *lpAddress)
{
struct sockaddr_in SockAddr;
int SockAddrLen=sizeof SockAddr;
struct hostent far *lpHostEnt;
Tcp4uLog (LOG4U_PROC, "TcpGetRemoteID on socket %d", s);
/* determiner l'adress IP de la station distante */
Tcp4uLog (LOG4U_DBCALL, "getpeername on socket %d", s);
if (getpeername (s, (struct sockaddr far *) & SockAddr, & SockAddrLen)==SOCKET_ERROR)
{
Tcp4uLog (LOG4U_ERROR, "getpeername on socket %d", s);
return TCP4U_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -