示例#1
0
/** Initialize an OSC-message with a raw byte-stream
 * (for instance from a network receiver).
 * The message object is reassembled from binary data. The length
 * must be known. When successfully reassembled, the arguments
 * (when existing) are accessable via the getNumXXX() and getXXX(int idx)
 * interface functions.
 *
 * \param buffer
 * Packet data containing the whole message with arguments.
 * 
 * \param bufferLen
 * Packet data length.
 * 
 * \throws WOscException
 * When corrupt initialization data, inconsistent bufferlengths etc. found.
 * 
 * \todo Since a message is defined, when its beginning is known
 * creating it from a byte stream without knowing the length would be
 * possible. Write an initializer.
 * 
 * \remarks
 * If an exception occurs, the construction of the message will be 
 * aborted, including the arguments.
 *
 * \todo
 * Add intensive exception handling for corrupt init data
 *
 * \see
 * WOscException | WOscString
 */
WOscMessage::WOscMessage(const char* buffer, int bufferLen){

	m_floats		= NULL;
	m_numFloats		= 0;
	m_ints			= NULL;
	m_numInts		= 0;
	m_strings		= NULL;
	m_numStrings	= 0;
	m_blobs			= NULL;
	m_numBlobs		= 0;

	m_buffer = NULL;

	// check address
	if (bufferLen < 1)
		throw new WOscException(
			WOscException::ERR_NULL_BUFFER,
			"WOscMessage: Message initialization buffer is empty.");
	// check address
	if (buffer[0] != '/')
		throw new WOscException(
			WOscException::ERR_INVALID_ADDRESS_NO_SLASH,
			"WOscMessage: Message address corrupt, no slash.");

	// extract address
	m_address = buffer;

	// get type tag
	int pos = m_address.GetSize();

	m_typeTag = W_OSC_EMPTY_TYPE_TAG; // init type tag
	

	if (bufferLen <= pos){
		// no type tag in buffer -> leave empty type tag
		GenerateBufferFromMembers();
		return;
	}

	WOscString OscTypeTag = buffer + pos;

	// get args by scanning typetag string
	const char* typeTag = OscTypeTag.GetBuffer();
	int typeTagSize = OscTypeTag.GetSize();
	pos += typeTagSize; // offset in buffer (beginning of argument data)

	for ( int i = 0; i < typeTagSize; i++ ){
		switch (typeTag[i]){
			case 'i':
				Add(WOscUtil::CharBufToInt(buffer + pos));
				pos += WOscUtil::OSC_INT_SIZE;
				break;
			case 'f':
				Add(WOscUtil::CharBufToFloat(buffer + pos));
				pos += WOscUtil::OSC_FLOAT_SIZE;
				break;
			case 's':
				Add(buffer+pos);
				pos += m_strings[m_numStrings-1].GetSize();
				break;
			case 'b':{
				WOscBlob* blob = new WOscBlob(buffer + pos);
				Add( blob );
				pos += blob->GetBufferLen();
				delete blob;
				break;
					 }

			case ',':
				break;
			case '\0':
				i = typeTagSize; // jump to end
				break;
			default: // error
				i = typeTagSize; // jump to end
				break;
		}
	}

	GenerateBufferFromMembers(); // generate arrays of arguments for later use with getXXX(int idx)
}
示例#2
0
int main()
{
	const char* default_serverurl = "localhost";
	short default_serverport = 7554;
	bool threading = false;
	WOscStreamingClient client(threading);

	//
	// Setup OSC address space
	//

	// containers
	WOscContainer* cntRoot = new WOscContainer();
	WOscContainer* cntTest = new WOscContainer(cntRoot, "test");

	// "root" methods
	WOscMethod* msgEcho = new WOscTcpHandlerMethod(cntRoot, &client, "printed", "printed description.");
	msgEcho->AddMethodAlias(cntTest, "echo");

	// add alias of method to same container where the original resides (to test the clean up)
	msgEcho->AddMethodAlias(cntTest, "echo2");

	// add alias of container to same container where the original resides (to test the clean up)
	cntTest->AddContainerAlias(cntRoot, "test2");

	client.SetAddressSpace(cntRoot);

	WOscString addressSpaceStr = cntRoot->GetAddressSpace();
	std::cout<<"Client address space:\n"<<addressSpaceStr.GetBuffer()<<std::flush;

	//
	// Connect to server
	//

	TheNetReturnAddress serverAddress;
	serverAddress.m_addr.sin_family = AF_INET;
	serverAddress.m_addr.sin_port = htons(default_serverport);
	if ( resolve(serverAddress.m_addr.sin_addr, default_serverurl) ) {
		std::cout<<"Resolved \""<<default_serverurl<<"\" successfully."<<std::endl;
	} else {
		std::cout<<"Failed to resolve \""<<default_serverurl<<"\". Defaulting to 127.0.0.1"<<std::endl;
		default_serverurl = "127.0.0.1";
		serverAddress.m_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	}
	std::cout<<"Connecting to \""<<default_serverurl<<"\" ("<<*inet_ntoa(serverAddress.m_addr.sin_addr) <<")."<<std::endl;

	WOscTcpClient::Error clientError = client.Connect(serverAddress);
	if ( clientError != WOscTcpClient::WOS_ERR_NO_ERROR ) {
		std::cout<<"Client connect failed with: "<<WOscTcpClient::GetErrStr(clientError)<<std::endl;
		return -1;
	}

	std::cout<<"Connected. Entering mainloop."<<std::endl;

	//
	// Main loop
	//
	WOscBundle theBundle;
	bool bundleOpen = false;

	while ( true ) {
		char input[1024];
		if ( threading ) {
			std::cin.getline(input,1024,'\n');
		} else {

			fd_set rfds;
			struct timeval tv;
			int retval;

			/* Watch stdin (fd 0) to see when it has input. */
			FD_ZERO(&rfds);
			FD_SET(0, &rfds);
			FD_SET(client.GetSocketID(), &rfds);

			/* Wait up to five seconds. */
			tv.tv_sec = 0;
			tv.tv_usec = 0;

			retval = select(client.GetSocketID()+1, &rfds, NULL, NULL, NULL/*&tv*/);
			/* Don't rely on the value of tv now! */

			if (retval == -1) {
				perror("select()");
				break;
			} else if (retval) {
				if ( FD_ISSET(0, &rfds) ) {
					std::cin.getline(input,1024,'\n');
				} else if ( FD_ISSET(client.GetSocketID(), &rfds) ) {
					WOscTcpClient::Error err = client.NetworkReceive();
					if ( err == WOscTcpClient::WOS_ERR_NO_ERROR )
						continue;
					else if ( err == WOscTcpClient::WOS_ERR_CONNECTION_CLOSED ) {
						std::cout<<"Connection has been closed by peer."<<std::endl;
						break;
					} else {
						std::cout<<"Connection failure on receive."<<std::endl;
						break;
					}
				} else {
					std::cout<<"No file descriptor for this select."<<std::endl;
					break;
				}
			} else {
				printf("Select timeout.\n");
				continue;
			}

		}

		if ( input[0] == '/' ) {
			// message assembly
			try {
				// parse parameters
				char* params[100];
				int nParams = 0;
				char* next = strchr ( input, ' ' );
				while ( next != 0 || nParams >= 100 ) {
					// add parameter to list
					params[nParams] = next + 1;
					// and zero-terminate previous
					*next = 0;
					// try to find new parameter
					next = strchr ( params[nParams++], ' ' );
				}

				// assemble message
				WOscMessage msg(input);
				// add parameters
				for ( int i = 0; i < nParams; i++ ) {
					int parInt = atoi(params[i]);
					float parFlt = atof(params[i]);
					// check if float
					if ( strchr ( params[i], '.' ) ) {
						msg.Add( parFlt );
					} else if ( parInt != 0 ) {
						msg.Add( parInt );
					} else {
						msg.Add( params[i] );
					}
				}
				// we pack message into bundle when open
				if ( bundleOpen ) {
					theBundle.Add(new WOscMessage(msg));
				} else {
					clientError = client.NetworkSend(msg.GetBuffer(), msg.GetBufferLen());
					if ( clientError != WOscTcpClient::WOS_ERR_NO_ERROR ) {
						std::cout<<"Client transmit failed with: "<<WOscTcpClient::GetErrStr(clientError)<<std::endl;
						break;
					}
				}
			} catch(const WOscException& e ) {
				std::cout<<"Exception: " << e.GetErrStr() <<std::endl;
			}
		}
		// open bundle
		else if (input[0] == '[') {
			if ( bundleOpen ) {
				std::cout<<"Bundle already open."<<std::endl;
			} else {
				theBundle.Reset();
				bundleOpen = true;
			}
		}
		// close bundle
		else if (input[0] == ']') {
			if ( bundleOpen ) {
				clientError = client.NetworkSend(theBundle.GetBuffer(), theBundle.GetBufferLen());
				if ( clientError != WOscTcpClient::WOS_ERR_NO_ERROR ) {
					std::cout<<"Client transmit of bundle failed with: "<<WOscTcpClient::GetErrStr(clientError)<<std::endl;
					break;
				}
				bundleOpen = false;
			} else {
				std::cout<<"No bundle to close."<<std::endl;
			}
		}
		// other commands
		else {
			// exit command
			if ( strcmp("exit",input) == 0 ) {
				break;
			}
			// help command
			else if ( strcmp("help",input) == 0 ) {
//				std::cout << WOSC_CLIENT_HELP_STR ;
			}
			// set local port (slp)
			else if  ( strncmp("slp",input,3) == 0 ) {
				/*
				localport = atoi( &input[4] );
				std::cout << "  Trying to set local port to " << localport << "."<<std::endl ;
				client.NetworkHalt();
				if ( client.NetworkInit( localport ) != WOscClient::WOS_ERR_NO_ERROR ) {
					std::cout << "Exit."<<std::endl ;
					return -1;
				}
				std::cout << "  Port successfully changed and network restarted."<<std::endl ;
				*/
			}
			// set remote port (srp)
			else if  ( strncmp("srp",input,3) == 0 ) {
				/*
				remoteport = atoi( &input[4] );
				std::cout << "  Remote port set to " << remoteport << "."<<std::endl ;
				*/
			}
			// set remote IP (srip)
			else if  ( strncmp("srip",input,4) == 0 ) {
				/*
				strcpy(remoteIP, &input[5]);
				std::cout << "  Remote IP set to " << remoteIP << "."<<std::endl ;
				*/
			}
		}
	}

	clientError = client.Close();
	if ( clientError != WOscTcpClient::WOS_ERR_NO_ERROR ) {
		std::cout<<"Client close failed with: "<<WOscTcpClient::GetErrStr(clientError)<<std::endl;
		return -1;
	}

	return 0;
}