www.pudn.com > udplib.rar > udplib.c


#define _UDPLIB_C 
 
#include "udplib.h" 
 
/* 
 * Open the network connection for the server. 
 *  nSockFd    :  the udp socket file identifier. 
 *  sService   :  the name of the service we provide. 
 *  nLocalPort :  if nonzero, this is the port to listen on 
 *		          overrides the standard port for the service. 
 *  noblock    :  if nonzero, not block while receiving. 
 */ 
int openUdpConn(int *nSockFd, char *sService, int nLocalPort, int noblock) 
{ 
	struct servent		*sp; 
	struct sockaddr_in	udp_srv_addr; 
	int    nRecvBuffSize; 
 
	*nSockFd = -1; 
	sp = NULL; 
	if ( sService!=NULL ) 
	{ 
		/* 
		 * We weren't started by a master daemon. 
		 * We have to create a socket ourselves and bind our well-known 
		 * address to it. 
		 */ 
		if ( (sp = getservbyname(sService, "udp"))==NULL ) 
		{ 
			perror( "getservbyname" ); 
			fprintf(stderr, "openUdpConn: unknown service: %s/udp\n", sService); 
		} 
		if ( nLocalPort>0 && sp!=NULL ) 
			sp->s_port = htons(nLocalPort);	/* caller's value */ 
	} 
	if ( ((*nSockFd)=socket(AF_INET, SOCK_DGRAM, 17))<0 ) 
	{ 
		perror( "socket" ); 
		fprintf( stderr, "openUdpConn: can't create datagram socket\n" ); 
		return -1; 
	} 
	/* 
	 * Bind our local address so that any client can send to us. 
	 */ 
	bzero( (char *)&udp_srv_addr, sizeof(udp_srv_addr) ); 
	udp_srv_addr.sin_family = AF_INET; 
	udp_srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
	if ( sp!=NULL ) 
		udp_srv_addr.sin_port = sp->s_port; 
	else if ( nLocalPort>0 ) 
		udp_srv_addr.sin_port = htons(nLocalPort); 
	else 
	{ 
		fprintf( stderr, "openUdpConn: no probable port\n" ); 
		return -1; 
	} 
	if ( bind(*nSockFd, (struct sockaddr *)&udp_srv_addr, 
					sizeof(udp_srv_addr))<0 ) 
	{ 
		perror( "bind" ); 
		fprintf( stderr, "openUdpConn: can't bind local address\n" ); 
		return -1; 
	} 
	if ( noblock ) 
	{ 
		/* 
		 * Set the socket to nonblocking, since program won't invoke 
		 * us unless there's a datagram ready for us to read. 
		 */ 
		noblock = 1; 
		if ( ioctl( *nSockFd, FIONBIO, &noblock)<0 ) 
		{ 
			perror( "ioctl" ); 
			fprintf( stderr, "openUdpNet: non-block failure\n" ); 
			return -1; 
		} 
	} 
    /* 
     * Set receive buffer size for udp 
     */ 
/* 
    nRecvBuffSize = 512*1024; 
    setsockopt(*nSockFd, SOL_SOCKET, SO_RCVBUF, &nRecvBuffSize, sizeof(nRecvBuffSize)); 
*/ 
 
	return 0; 
}	/* end openUdpConn() */ 
 
/* 
 * Receive a packet from the other end. 
 * Return the length of packet, 
 *  nSockFd  :  the udp socket file identifier. 
 *  sBuff    :	the contents of packet that we received. 
 *  nMaxLen  :	the maximum length of contents for receiving. 
 *  fromaddr :	the address of the other end which sends this record. 
 *  fromport :	the port of the other end which sends this record. 
 */ 
int recvPacketFromUdp(int nSockFd, char *sBuff, int nMaxLen, 
                      u_long *fromaddr, u_short *fromport) 
{ 
	struct sockaddr_in	udp_cli_addr; 
	int			addrlen, buflen; 
	int			packetlen; 
 
	addrlen = sizeof( udp_cli_addr ); 
	if ( (buflen=recvfrom( nSockFd, sBuff, nMaxLen, 0, 
			(struct sockaddr *)&udp_cli_addr, &addrlen ))<0 ) 
		return (-1); 
	*fromaddr = udp_cli_addr.sin_addr.s_addr; 
	*fromport = udp_cli_addr.sin_port; 
 
	sBuff[buflen] = '\0'; 
	sscanf( sBuff, "%4d", &packetlen ); 
	if ( packetlen>0 && packetlen0 ) 
		memcpy( sendbuff+sizeOfPckLen, sBuff, nLen ); 
	else 
		return -1; 
 
	nLen += sizeOfPckLen; 
	sendbuff[nLen] = '\0'; 
	if ( sendto( nSockFd, sendbuff, nLen, 0, 
			(struct sockaddr *)&udp_cli_addr, addrlen )<0 ) 
		return (-1); 
 
	return (nLen-sizeOfPckLen); 
}	/* end sendPacketToUdp() */ 
 
/* 
 * Close the connection. 
 */ 
void closeUdpConn(int nSockFd) 
{ 
	if ( nSockFd>=0 ) 
		close( nSockFd ); 
}	/* end closeUdpConn() */