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

📄 observer.cpp

📁 UAV 自动驾驶的
💻 CPP
字号:
/** *  $Id: Observer.cpp,v 2.0 2002/09/22 02:07:32 tramm Exp $ */#include "Observer.h"#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <unistd.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>using namespace std;namespace Observer{static std::ostream &operator << (	std::ostream &		out,	const client_t &	client){	uint32_t		bytes = client.sin_addr.s_addr;	return out		<< "[" << ((bytes >>  0) & 0xFF)		<< "." << ((bytes >>  8) & 0xFF)		<< "." << ((bytes >> 16) & 0xFF)		<< "." << ((bytes >> 24) & 0xFF)		<< ":" << ntohs( client.sin_port )		<< "]";}booloperator != (	const sockaddr_in &	a,	const sockaddr_in &	b){	return a.sin_addr.s_addr != b.sin_addr.s_addr	||            a.sin_port != b.sin_port;}Server::Server(	int			port){	int			s = socket(		PF_INET,		SOCK_DGRAM,		0	);	if( s < 0 )	{		perror( "Server: socket" );		return;	}	struct sockaddr_in	addr;	addr.sin_family		= AF_INET;	addr.sin_port		= htons( port );	addr.sin_addr.s_addr	= INADDR_ANY;	if( bind(		s,		(struct sockaddr*) &addr,		sizeof( addr )	) < 0 )	{		perror( "Server: bind" );		return;	}	this->sock		= s;}Server::~Server(){	if( this->sock >= 0 )		close( this->sock );	this->sock		= -1;}boolServer::connect(	const char *		hostname,	int			port){	if( hostname == 0 )		hostname = "localhost";	if( port == 0 )		port = 2002;	struct hostent *	hp;	struct sockaddr_in	server;	if( !(hp = gethostbyname( hostname )) )	{		perror( hostname );		return false;	}	server.sin_family	= AF_INET;	server.sin_port		= htons( port );	memcpy(		&server.sin_addr,		hp->h_addr,		hp->h_length	);	this->server		= server;	return true;}voidServer::sendme(	uint32_t		msgtype){	msg_hdr_t		hdr;	hdr.command	= SENDME;	hdr.type	= msgtype;	gettimeofday( &hdr.tv, 0 );	this->write(		&this->server,		&hdr,		sizeof(hdr)	);}voidServer::nosend(	uint32_t		msgtype){	msg_hdr_t		hdr;	hdr.command	= NOSEND;	hdr.type	= msgtype;	gettimeofday( &hdr.tv, 0 );	this->write(		&this->server,		&hdr,		sizeof(hdr)	);}boolServer::poll(	int			usec){	if( this->sock < 0 )		return false;	fd_set			fds;	FD_ZERO( &fds );	FD_SET( this->sock, &fds );	struct timeval		tv = { 0, usec };	int			rc;	rc = select(		this->sock+1,		&fds,		0,		0, 		usec >= 0 ? &tv : 0	);	return rc;}ssize_tServer::read(	void *			buf,	size_t			bufmax,	client_t *		client){	if( this->sock < 0 )		return -1;	struct sockaddr_in	addr;	socklen_t		addr_len = sizeof(addr);	int			rc;	rc = recvfrom(		this->sock,		buf,		bufmax,		0,		(struct sockaddr *) &addr,		&addr_len	);	if( rc < 0 )	{		perror( "recvfrom" );		return -1;	}	*client = *(client_t*) &addr;	return rc;}boolServer::write(	client_t *		dest,	const void *		buf,	size_t			buflen){	int			rc;	rc = sendto(		this->sock,		buf,		buflen,		0,		(struct sockaddr *) dest,		sizeof( *dest )	);	if( rc < 0 )		perror( "write" );	return rc < 0;}voidServer::do_sendme(	uint32_t		msgtype,	client_t *		client){	client_list_t &		cl( this->clients[msgtype] );	cl.push_back( *client );}voidServer::do_nosend(	uint32_t		msgtype,	client_t *		client){	client_list_t &		cl( this->clients[msgtype] );	for( client_list_t::iterator i = cl.begin() ;		i != cl.end() ;		i++	)	{		if( *i != *client )			continue;		cl.erase( i );		break;	}}voidServer::resend(	uint32_t		msgtype,	const void *		buf,	size_t			len){	client_list_t &		cl( this->clients[msgtype] );	for( client_list_t::iterator i = cl.begin();		i != cl.end();		i++	)	{		this->write( i, buf, len );	}}voidServer::send(	uint32_t		msgtype,	const void *		user_buf,	size_t			len){	char			buf[ 65536 ];	msg_hdr_t *		hdr = (msg_hdr_t*) &buf[0];	hdr->command	= OBJECT;	hdr->type	= msgtype;	gettimeofday( &hdr->tv, 0 );	if( len > sizeof(buf) )	{		cerr << "Server::send: len=" << len			<< " > 65536" << endl;		return;	}	memcpy( buf + sizeof( msg_hdr_t ), user_buf, len );	this->write(		&this->server,		buf,		sizeof(msg_hdr_t) + len	);}boolServer::handle(){	char			buf[ 4096 ];	ssize_t			len;	client_t		client;	len = this->read( buf, sizeof(buf), &client );	cout << "Read " << len << " bytes from " << client << endl;	const msg_hdr_t *	hdr = (msg_hdr_t*) &buf[0];	cout << "Command: "		<< hex		<< hdr->command		<< ":"		<< hdr->type		<< dec		<< endl;	switch( hdr->command )	{	case NOP:	case ACK:	case NACK:		break;	case SENDME:		this->do_sendme( hdr->type, &client );		break;	case NOSEND:		this->do_nosend( hdr->type, &client );		break;	case OBJECT:	{		this->resend( hdr->type, buf, len );		handler_map_t::iterator i = this->handlers.find( hdr->type );		if( i == this->handlers.end() )			break;		handler_pair_t &handler( i->second );		handler.first(			hdr->type,			buf + sizeof(*hdr), 			len - sizeof(*hdr),			handler.second		);		break;	}	default:		cerr << "Unhandled command: "			<< hex			<< hdr->command			<< ":"			<< hdr->type			<< dec			<< endl;		break;	}	return true;}/* *  Local handlers */voidServer::subscribe(	uint32_t		msgtype,	handler_t		handler,	void *			user_data){	this->handlers[msgtype] = handler_pair_t( handler, user_data );}voidServer::unsubscribe(	uint32_t		msgtype){	this->handlers.erase( msgtype );}}

⌨️ 快捷键说明

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