Initial revision
This commit is contained in:
705
network.c
Normal file
705
network.c
Normal file
@@ -0,0 +1,705 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Some metworking functions. This version for TCP/IP.
|
||||
|
||||
|
||||
|
||||
|
||||
Mark Koennecke, October 1996
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
Paul Scherrer Institut
|
||||
CH-5423 Villigen-PSI
|
||||
|
||||
|
||||
The authors hereby grant permission to use, copy, modify, distribute,
|
||||
and license this software and its documentation for any purpose, provided
|
||||
that existing copyright notices are retained in all copies and that this
|
||||
notice is included verbatim in any distributions. No written agreement,
|
||||
license, or royalty fee is required for any of the authorized uses.
|
||||
Modifications to this software may be copyrighted by their authors
|
||||
and need not follow the licensing terms described here, provided that
|
||||
the new terms are clearly indicated on the first page of each file where
|
||||
they apply.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
----------------------------------------------------------------------------*/
|
||||
#include "fortify.h"
|
||||
#include "network.h"
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define PORT 1
|
||||
#define SOCKET 2
|
||||
#define UDP 3
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
Redefine this function if another means of error reporting is necessary.
|
||||
*/
|
||||
#include "Scommon.h"
|
||||
extern void SICSLogWrite(char *pText, OutCode eCode); /* servlog.c */
|
||||
|
||||
static void NetError(char *pText)
|
||||
{
|
||||
SICSLogWrite(pText,eError);
|
||||
}
|
||||
|
||||
/* ---------------------------- Local ------------------------------------
|
||||
CreateSocketAdress stolen from Tcl. Thanks to John Ousterhout
|
||||
*/
|
||||
|
||||
static int
|
||||
CreateSocketAdress(
|
||||
struct sockaddr_in *sockaddrPtr, /* Socket address */
|
||||
char *host, /* Host. NULL implies INADDR_ANY */
|
||||
int port) /* Port number */
|
||||
{
|
||||
struct hostent *hostent; /* Host database entry */
|
||||
struct in_addr addr; /* For 64/32 bit madness */
|
||||
|
||||
(void) memset((char *) sockaddrPtr, '\0', sizeof(struct sockaddr_in));
|
||||
sockaddrPtr->sin_family = AF_INET;
|
||||
sockaddrPtr->sin_port = htons((unsigned short) (port & 0xFFFF));
|
||||
if (host == NULL) {
|
||||
addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
hostent = gethostbyname(host);
|
||||
if (hostent != NULL) {
|
||||
memcpy((char *) &addr,
|
||||
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
|
||||
} else {
|
||||
addr.s_addr = inet_addr(host);
|
||||
if (addr.s_addr == (unsigned long)-1) {
|
||||
return 0; /* error */
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* There is a rumor that this assignment may require care on
|
||||
* some 64 bit machines.
|
||||
*/
|
||||
|
||||
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
mkChannel *NETOpenPort(int iPort)
|
||||
{
|
||||
mkChannel *pRes = NULL;
|
||||
int iRet,i;
|
||||
struct linger lili;
|
||||
|
||||
pRes = (mkChannel *)malloc(sizeof(mkChannel));
|
||||
if(!pRes)
|
||||
return NULL;
|
||||
|
||||
/* open a socket */
|
||||
pRes->sockid = socket(AF_INET,SOCK_STREAM,0);
|
||||
if(pRes->sockid < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* REUSEADDR, for restarts */
|
||||
i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
|
||||
/* bind */
|
||||
memset(&(pRes->adresse),0,sizeof(struct sockaddr_in));
|
||||
pRes->adresse.sin_family = AF_INET;
|
||||
pRes->adresse.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
pRes->adresse.sin_port = htons(iPort);
|
||||
iRet = bind(pRes->sockid,(struct sockaddr *)&(pRes->adresse),
|
||||
sizeof(struct sockaddr_in));
|
||||
if(iRet < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* listen */
|
||||
iRet = listen(pRes->sockid,8);
|
||||
if(iRet < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
i = sizeof(struct linger);
|
||||
lili.l_onoff = 1;
|
||||
lili.l_linger = 1;
|
||||
/* setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
|
||||
*/
|
||||
pRes->iType = PORT;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
mkChannel *NETAccept(mkChannel *self, int timeout)
|
||||
{
|
||||
mkChannel *pRes = NULL;
|
||||
int iRet;
|
||||
fd_set lMask;
|
||||
struct timeval tmo = {1,0};
|
||||
int iLen, i;
|
||||
struct linger lili;
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
/* select first */
|
||||
tmo.tv_usec = timeout;
|
||||
FD_ZERO(&lMask);
|
||||
FD_SET(self->sockid,&lMask);
|
||||
if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) ) /* invalid descriptor */
|
||||
{
|
||||
return NULL; /* eof */
|
||||
}
|
||||
iRet = select( (self->sockid + 1),(fd_set *)&lMask, NULL, NULL,&tmo);
|
||||
if( iRet <= 0)
|
||||
{
|
||||
/* failure, or no request */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* positive: accept */
|
||||
iLen = sizeof(struct sockaddr);
|
||||
pRes = (mkChannel *)malloc(sizeof(mkChannel));
|
||||
if(!pRes) return NULL;
|
||||
|
||||
pRes->sockid = accept(self->sockid,
|
||||
(struct sockaddr *)&(pRes->adresse),
|
||||
&iLen);
|
||||
if(pRes->sockid < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
i = sizeof(struct linger);
|
||||
lili.l_onoff = 1;
|
||||
lili.l_linger = 1;
|
||||
/* setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
|
||||
i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
*/ pRes->iType = SOCKET;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
mkChannel *NETConnect(char *name, int port)
|
||||
{
|
||||
mkChannel *pRes = NULL;
|
||||
int iRet, i;
|
||||
char pBueffel[80];
|
||||
struct hostent *pServer = NULL;
|
||||
struct linger lili;
|
||||
|
||||
assert(port > 0);
|
||||
|
||||
/* default name to localhost */
|
||||
if(name == NULL)
|
||||
{
|
||||
strcpy(pBueffel,"localhost");
|
||||
name = pBueffel;
|
||||
}
|
||||
|
||||
/* new channel */
|
||||
pRes = (mkChannel *)malloc(sizeof(mkChannel));
|
||||
if(!pRes)
|
||||
return NULL;
|
||||
|
||||
/* connect */
|
||||
iRet = CreateSocketAdress(&(pRes->adresse),name,port);
|
||||
if(!iRet)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
pRes->sockid = socket(AF_INET,SOCK_STREAM,0);
|
||||
if(pRes->sockid < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
iRet = connect(pRes->sockid,(struct sockaddr *)&(pRes->adresse),
|
||||
sizeof(struct sockaddr_in));
|
||||
|
||||
if(iRet < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
i = sizeof(struct linger);
|
||||
lili.l_onoff = 1;
|
||||
lili.l_linger = 1;
|
||||
/* setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
|
||||
i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
*/ pRes->iType = SOCKET;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int VerifyChannel(mkChannel *self)
|
||||
{
|
||||
if(!self)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(self->lMagic != NETMAGIC)
|
||||
{
|
||||
NetError("CORRUPTED MAGIC: network channel data corrupted");
|
||||
return 0;
|
||||
}
|
||||
if( (self->sockid < 0) || (self->sockid > 65000) )
|
||||
{
|
||||
NetError("MAGIC DEAD: Invalid socket number, data corrupted");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
int NETInfo(mkChannel *self, char *pCompost, int iBufLen)
|
||||
{
|
||||
|
||||
int t;
|
||||
int len;
|
||||
struct sockaddr_in sin;
|
||||
struct hostent *host;
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sizeof sin;
|
||||
if (getpeername(self->sockid, (struct sockaddr *) &sin, &len) < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((host = gethostbyaddr((char *) &sin.sin_addr,
|
||||
sizeof sin.sin_addr,
|
||||
AF_INET)) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(pCompost,host->h_name,iBufLen);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int NETWrite(mkChannel *self, char *buffer, long lLen)
|
||||
{
|
||||
int iRet;
|
||||
fd_set lMask;
|
||||
struct timeval tmo ={0,1};
|
||||
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(!(self->iType == SOCKET))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup for select first */
|
||||
tmo.tv_usec = 100;
|
||||
FD_ZERO(&lMask);
|
||||
FD_SET(self->sockid,&lMask);
|
||||
if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) )
|
||||
/* invalid descriptor */
|
||||
{
|
||||
return -1; /* eof */
|
||||
}
|
||||
#ifndef CYGNUS
|
||||
iRet = select( (self->sockid + 1),NULL, &lMask, NULL,&tmo);
|
||||
if( iRet <= 0)
|
||||
{
|
||||
/* failure, or no data */
|
||||
return -1;
|
||||
}
|
||||
/* blocking on write */
|
||||
if(!FD_ISSET(self->sockid,&lMask))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
iRet = send(self->sockid,buffer,lLen,0);
|
||||
if(iRet != lLen)
|
||||
{
|
||||
/* puts("Incomplete send "); */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
/* -------------------------------------------------------------------------*/
|
||||
long NETRead(mkChannel *self, char *buffer, long lLen, int timeout)
|
||||
{
|
||||
fd_set lMask;
|
||||
struct timeval tmo ={0,1};
|
||||
long iRet;
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
/* setup for select first */
|
||||
tmo.tv_usec = timeout;
|
||||
FD_ZERO(&lMask);
|
||||
FD_SET(self->sockid,&lMask);
|
||||
if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) ) /* invalid descriptor */
|
||||
{
|
||||
return -1; /* eof */
|
||||
}
|
||||
iRet = select( (self->sockid + 1),&lMask, NULL, NULL,&tmo);
|
||||
if( iRet <= 0)
|
||||
{
|
||||
/* failure, or no data */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* data or block for read, read */
|
||||
buffer[0] = '\0';
|
||||
iRet = recv(self->sockid,buffer,lLen,0);
|
||||
if(iRet == 0)
|
||||
{/* eof */
|
||||
return -1;
|
||||
}
|
||||
if(iRet < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[iRet] = '\0';
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int NETClosePort(mkChannel *self)
|
||||
{
|
||||
int iRet;
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(self->sockid);
|
||||
self->iType = 0;
|
||||
self->sockid = 0;
|
||||
if(iRet < 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
|
||||
}
|
||||
/* ################### UDP -functions ######################################*/
|
||||
mkChannel *UDPOpen(int iPort)
|
||||
{
|
||||
mkChannel *pRes = NULL;
|
||||
int iRet, i;
|
||||
|
||||
pRes = (mkChannel *)malloc(sizeof(mkChannel));
|
||||
if(!pRes)
|
||||
return NULL;
|
||||
|
||||
/* open a socket */
|
||||
pRes->sockid = socket(AF_INET,SOCK_DGRAM,0);
|
||||
if(pRes->sockid < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* REUSEADDR for restarting ability */
|
||||
i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
|
||||
assert(pRes->sockid < (sizeof(long)*8));
|
||||
/* if this fails the masks for select will be to
|
||||
short.
|
||||
*/
|
||||
|
||||
|
||||
/* bind */
|
||||
memset(&(pRes->adresse),0,sizeof(struct sockaddr_in));
|
||||
pRes->adresse.sin_family = AF_INET;
|
||||
pRes->adresse.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
pRes->adresse.sin_port = htons(iPort);
|
||||
iRet = bind(pRes->sockid,(struct sockaddr *)&(pRes->adresse),
|
||||
sizeof(struct sockaddr_in));
|
||||
if(iRet < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRes->iType = UDP;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
mkChannel *UDPConnect(char *name, int port)
|
||||
{
|
||||
mkChannel *pRes = NULL;
|
||||
int iRet, i;
|
||||
char pBueffel[80];
|
||||
struct hostent *pServer = NULL;
|
||||
|
||||
assert(port > 0);
|
||||
|
||||
/* default name to localhost */
|
||||
if(name == NULL)
|
||||
{
|
||||
strcpy(pBueffel,"localhost");
|
||||
name = pBueffel;
|
||||
}
|
||||
|
||||
/* new channel */
|
||||
pRes = (mkChannel *)malloc(sizeof(mkChannel));
|
||||
if(!pRes)
|
||||
return NULL;
|
||||
|
||||
/* connect */
|
||||
iRet = CreateSocketAdress(&(pRes->adresse),name,port);
|
||||
if(!iRet)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
pRes->sockid = socket(AF_INET,SOCK_DGRAM,0);
|
||||
if(pRes->sockid < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
iRet = connect(pRes->sockid,(struct sockaddr *)&(pRes->adresse),
|
||||
sizeof(struct sockaddr_in));
|
||||
*/
|
||||
iRet = 1;
|
||||
if(iRet < 0)
|
||||
{
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
*/
|
||||
pRes->iType = UDP;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
long UDPRead(mkChannel *self, char *buffer, long lLen, int timeout)
|
||||
{
|
||||
long lMask = 0L;
|
||||
struct timeval tmo ={0,1};
|
||||
long iRet;
|
||||
int iLang;
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
assert(self->iType == UDP);
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
/* setup for select first */
|
||||
tmo.tv_usec = timeout;
|
||||
lMask = (1 << self->sockid);
|
||||
iRet = select( (self->sockid + 1),(fd_set *)&lMask, NULL, NULL,&tmo);
|
||||
if( iRet <= 0)
|
||||
{
|
||||
/* failure, or no data */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* data, read */
|
||||
buffer[0] = '\0';
|
||||
iLang = sizeof(struct sockaddr_in);
|
||||
iRet = recvfrom(self->sockid,buffer,lLen,0,
|
||||
(struct sockaddr *)&(self->adresse),
|
||||
&iLang);
|
||||
if(iRet == 0)
|
||||
{/* eof */
|
||||
return -1;
|
||||
}
|
||||
if(iRet < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[iRet] = '\0';
|
||||
return iRet;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int UDPWrite(mkChannel *self, char *buffer, long lLen)
|
||||
{
|
||||
int iRet;
|
||||
|
||||
if(!VerifyChannel(self))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
assert(self->iType == UDP);
|
||||
|
||||
iRet = sendto(self->sockid,buffer,lLen,0,
|
||||
(struct sockaddr *)&(self->adresse),sizeof(struct sockaddr_in));
|
||||
fsync(self->sockid);
|
||||
if(iRet < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
|
||||
TestCode. Compile with DBCLIENT defined to get a test client,
|
||||
with DBSERVER defined to get a test server.
|
||||
*/
|
||||
|
||||
#ifdef DBCLIENT
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char pBueffel[80];
|
||||
mkChannel *pChan = NULL;
|
||||
int iRet;
|
||||
|
||||
pChan = NETConnect("localhost",4711);
|
||||
if(!pChan)
|
||||
{
|
||||
puts("No connection to server");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
printf("Client> ");
|
||||
gets(pBueffel);
|
||||
if(strcmp(pBueffel,"exit") == 0)
|
||||
break;
|
||||
iRet = NETWrite(pChan,pBueffel,strlen(pBueffel));
|
||||
if(!iRet)
|
||||
puts("Write error");
|
||||
|
||||
iRet = NETRead(pChan,pBueffel,79,2000);
|
||||
if(iRet < -1)
|
||||
{
|
||||
puts("Read error");
|
||||
}
|
||||
else if(iRet > 0)
|
||||
{
|
||||
pBueffel[iRet] = '\0';
|
||||
puts(pBueffel);
|
||||
}
|
||||
}
|
||||
NETClosePort(pChan);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DBSERVER
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
mkChannel *pPort = NULL;
|
||||
mkChannel *pCon[20];
|
||||
int i,iRet, iPtr = 0;
|
||||
char pBueffel[132];
|
||||
|
||||
pPort = NETOpenPort(4711);
|
||||
if(!pPort)
|
||||
{
|
||||
puts("Cannot start server");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* accept new connections */
|
||||
pCon[iPtr] = NETAccept(pPort,200);
|
||||
if(pCon[iPtr])
|
||||
{
|
||||
printf("Connection accepted on socket %d\n",pCon[iPtr]->sockid);
|
||||
iPtr++;
|
||||
}
|
||||
|
||||
/* look for messages */
|
||||
for(i = 0; i < iPtr; i++)
|
||||
{
|
||||
if(pCon[i])
|
||||
{
|
||||
iRet = NETRead(pCon[i],pBueffel,131,200);
|
||||
if(iRet < 0)
|
||||
{
|
||||
printf("closing socket %d\n",pCon[i]->sockid);
|
||||
NETClosePort(pCon[i]);
|
||||
free(pCon[i]);
|
||||
pCon[i] = NULL;
|
||||
}
|
||||
else if(iRet > 0)
|
||||
{
|
||||
pBueffel[iRet] = '\0';
|
||||
printf("Received - %s - from %d\n",pBueffel,pCon[i]->sockid);
|
||||
NETWrite(pCon[i],"Acknowledge",strlen("Acknowledge"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user