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

📄 udpmessagesocket.cpp

📁 kphone-4.2,SHELL协议的VOIP电话
💻 CPP
字号:
#include <sys/types.h>#include <sys/socket.h>#include <netinet/ip.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <stdio.h>#include <unistd.h>#include <strings.h>#include "udpmessagesocket.h"UDPMessageSocket::UDPMessageSocket( void ){	type = SocketUDP;	if ( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {		perror( "UDPMessageSocket::UDPMessageSocket(): socket() failed" );	}	didcomplain = false;}UDPMessageSocket::UDPMessageSocket( int newfd ){	type = SocketUDP;	socketfd = newfd;	didcomplain = false;}UDPMessageSocket::~UDPMessageSocket( void ){	close( socketfd );}int UDPMessageSocket::connect( unsigned int portnum ){	socketaddress.sin_family = AF_INET;	socketaddress.sin_port = htons( portnum );	socketaddress.sin_addr = *( (struct in_addr *) he->h_addr );	bzero( &(socketaddress.sin_zero), 8 ); // is this portable?	remoteaddress = socketaddress;	return 0;}int UDPMessageSocket::SetTOS( void ){	unsigned char tos;	socklen_t optlen;#ifdef WIN32      // Don't use IPTOS_PREC_CRITIC_ECP on Unix platforms as then need to be root	tos=IPTOS_PREC_CRITIC_ECP|IPTOS_LOWDELAY;#else 	tos=IPTOS_LOWDELAY;#endif	optlen=1;	if(setsockopt(socketfd,SOL_IP,IP_TOS,&tos,optlen) != 0){		perror("UDPMessageSocket::SetTOS");                return -1 ;	}	return 0;}int UDPMessageSocket::send( const char *sendbuffer, unsigned int length ){	int numbytes;	if( ( numbytes = sendto( socketfd, sendbuffer, length, 0,	    (struct sockaddr *) &remoteaddress, sizeof( struct sockaddr ) ) ) == -1 ) {		if( !didcomplain ) {			perror( "UDPMessageSocket::send(): sendto() failed" );			didcomplain = true;		}		return -1;	}	return 0;}int UDPMessageSocket::receive( char *recvbuffer, unsigned int maxlength ){	socklen_t addrlength;	int numbytes;	addrlength = sizeof( struct sockaddr );	if( ( numbytes = recvfrom( socketfd, recvbuffer, maxlength, 0, \	    (struct sockaddr *) &remoteaddress, &addrlength ) ) == -1 ) {		perror( "UDPMessageSocket::recieve(): recvfrom() failed" );		return -1;	}	return numbytes;}unsigned int UDPMessageSocket::listen( unsigned int portnum ){	struct sockaddr name;	socklen_t namesize;	socketaddress.sin_family = AF_INET;	socketaddress.sin_port = htons( portnum );	socketaddress.sin_addr.s_addr = INADDR_ANY;	bzero( &(socketaddress.sin_zero), 8 ); // is this portable?	/*	 * if already bound then close this one and open	 * a new socket so we can bind it to different port	 * number	 */	if (bound) {		close(socketfd);		bound = false;		if( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {			perror( "UDPMessageSocket::listen: socket() failed" );			return 0;		}	}	int count = 0;	while ( bind( socketfd, (struct sockaddr *) &socketaddress, sizeof( struct sockaddr) ) == -1 && count <= 10 ) {		count++;		portnum += 2;		socketaddress.sin_port = htons( portnum );	}	if ( count > 10 ) {		perror( "UDPMessageSocket::listen(): bind() failed" );		return 0;	}	bound = true;	namesize = sizeof( struct sockaddr );	bzero( &name, sizeof( struct sockaddr ) );	if ( getsockname( socketfd, &name, &namesize ) == -1 ) {		perror( "UDPMessageSocket::listen(): getsockname() failed" );		return 0;	}	ourport = ntohs( ((struct sockaddr_in *) &name)->sin_port );	return ourport;}/* * FIXME: There is no guarantee that the subsequent call * to socket and bind will return previous port number + 1 ! * This function can potentially allocate several file * descriptors and never close them * comment made by jan@iptel.org */int UDPMessageSocket::listenOnEvenPortOS( void ){	struct sockaddr name;	socklen_t namesize;	int oldsocketfd = 0;	int portnum = 0;	/*	 * if already bound then close this one and open	 * a new socket so we can bind it to different port	 * number	 */	if (bound) {		close(socketfd);		bound = false;		if( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {			perror( "UDPMessageSocket::listenOnEvenPortOS: socket() failed" );			return -1;		}	}getaddress:	socketaddress.sin_family = AF_INET;	socketaddress.sin_port = htons( portnum );	socketaddress.sin_addr.s_addr = INADDR_ANY;	bzero( &(socketaddress.sin_zero), 8 ); // is this portable?	if ( bind( socketfd, (struct sockaddr *) &socketaddress, sizeof( struct sockaddr) ) == -1 ) {		perror( "UDPMessageSocket::listen(): bind() failed" );		return -1;	}	bound = true;	namesize = sizeof( struct sockaddr );	bzero( &name, sizeof( struct sockaddr ) );	if ( getsockname( socketfd, &name, &namesize ) == -1 ) {		perror( "UDPMessageSocket::listen(): getsockname() failed" );		return -1;	}	ourport = ntohs( ((struct sockaddr_in *) &name)->sin_port );	printf( "UDPMessageSocket: Listening on %d\n", ourport );	if( ( portnum == 0 ) && ( ourport % 2 ) != 0 ) {		printf( "UDPMessageSocket: Retrying...\n" );		oldsocketfd = socketfd;		if( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {			perror( "UDPMessageSocket::UDPMessageSocket(): socket() failed" );		}		goto getaddress;	}	if( oldsocketfd != 0 )		close( oldsocketfd );	return 0;}int UDPMessageSocket::listenOnEvenPort(int min, int max){	/* User didn't specify any range, let the OS	 * assign source port number	 */	if ((min == 0) && (max == 0)) {		return listenOnEvenPortOS();	}	/* Only max specified, set min to the lowest limit */	if (min == 0) min = 1024;	/* Only min specified, set max to the highest port number */	if (max == 0) max = 65535;	/* min not odd, increase */	if (min % 2) min++;	/* Out of range ? Signal error */	if (min > max) goto error;	/*	 * if already bound then close this one and open	 * a new socket so we can bind it to different port	 * number	 */	if (bound) {		close(socketfd);		bound = false;		if( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {			perror( "UDPMessageSocket::listenOnEvenPor: socket() failed" );			return -1;		}	}loop:	socketaddress.sin_family = AF_INET;	socketaddress.sin_port = htons(min);	socketaddress.sin_addr.s_addr = INADDR_ANY;	bzero(&(socketaddress.sin_zero), 8);	if (bind(socketfd, (struct sockaddr*)&socketaddress, sizeof(struct sockaddr)) == -1) {		min += 2;		if (min <= max) goto loop;		else goto error;	}		bound = true;	/*	 * FIXME: Do some test for even port number here	 */	ourport = min;	printf("UDPMessageSocket: Listening on %d\n", min);	return 0;error:	perror("UDPMessageSocket::listen(): Can't find a free port in specified range");	return -1;	}int UDPMessageSocket::listenOnEvenPortForVideo( void ){	struct sockaddr name;	socklen_t namesize;	int oldsocketfd = 0;	int portnum = 0;	if ( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {		perror( "UDPMessageSocket::UDPMessageSocket(): socket() failed" );	}getaddress:	socketaddress.sin_family = AF_INET;	socketaddress.sin_port = htons( portnum );	socketaddress.sin_addr.s_addr = INADDR_ANY;	bzero( &(socketaddress.sin_zero), 8 ); // is this portable?	int one = 1;	if ( setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof( one ) ) == -1 ) {		perror( "UDPMessageSocket::setsockopt SO_REUSEADDR" );	}	if ( bind( socketfd, (struct sockaddr *) &socketaddress, sizeof( struct sockaddr) ) == -1 ) {		perror( "UDPMessageSocket::listen(): bind() failed" );		return -1;	}	bound = true;	namesize = sizeof( struct sockaddr );	bzero( &name, sizeof( struct sockaddr ) );	if ( getsockname( socketfd, &name, &namesize ) == -1 ) {		perror( "UDPMessageSocket::listen(): getsockname() failed" );		return -1;	}	ourport = ntohs( ((struct sockaddr_in *) &name)->sin_port );	printf( "UDPMessageSocket (video): Listening on %d\n", ourport );	if( portnum == 0 && ( ourport % 4 ) != 0 ) {		printf( "UDPMessageSocket: Retrying...\n" );		oldsocketfd = socketfd;		if( ( socketfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 ) {			perror( "UDPMessageSocket::UDPMessageSocket(): socket() failed" );		}		goto getaddress;	}	if( oldsocketfd != 0 )		close( oldsocketfd );	return 0;}int UDPMessageSocket::accept( void ){	return socketfd;}

⌨️ 快捷键说明

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