Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » [Solved]XML Rpc client will halt when server is not running
[Solved]XML Rpc client will halt when server is not running [message #36611] Wed, 20 June 2012 12:58 Go to next message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
The following code will halt when XML RPC Server is not running.

#include <Core/Core.h>
#include <Core/XMLRpc/XMLRpc.h>

using namespace Upp;

namespace Upp { 
	extern bool HttpRequest_Trace__;
}

int main() {
#ifdef flagDEBUG
//	LogXmlRpcRequests();
//	HttpRequest_Trace__ = true;
	StdLogSetup( LOG_COUT | LOG_FILE );	
#endif

	Time serverTime;
	SetDateFormat( "%4d-%02d-%02d" );
	XmlRpcRequest call( "127.0.0.1:1234" );
	if( call("GetServerTime") >> serverTime ) {
		LOG( "Server Time =" + Upp::AsString(serverTime) );
	}
	else {
		LOG( Upp::Format("Error: %s", call.GetError()) );
	}

	return 0;
}


I try to trace the code, the problem seems to happen in the red block. (In upp\uppsrc\Core\Socket.cpp)

int TcpSocket::Put(const char *s, int length)
{
	LLOG("Put " << socket << ": " << length);
	ASSERT(IsOpen());
	if(length < 0 && s)
		length = (int)strlen(s);
	if(!s || length <= 0 || IsError() || IsAbort())
		return 0;
	done = 0;
	bool peek = false;
	int end_time = GetEndTime();

	while(done < length) {
		if(peek && !Wait(WAIT_WRITE, end_time))
			return done;
		peek = false;
		int count = Send(s + done, length - done);
		if(IsError() || timeout == 0 && count == 0 && peek)
			return done;
		if(count > 0)
			done += count;
		else
			peek = true;
	}

	LLOG("//Put() -> " << done);
	return done;
}


I modify the code from (In upp\uppsrc\Core\Socket.cpp)

bool TcpSocket::WouldBlock()
{
	int c = GetErrorCode();
#ifdef PLATFORM_POSIX
	return c == SOCKERR(EWOULDBLOCK) || c == SOCKERR(EAGAIN);
#endif
#ifdef PLATFORM_WIN32
	return c == SOCKERR(EWOULDBLOCK) || c == SOCKERR(ENOTCONN);
#endif
}


to

bool TcpSocket::WouldBlock()
{
	int c = GetErrorCode();
#ifdef PLATFORM_POSIX
	return c == SOCKERR(EWOULDBLOCK) || c == SOCKERR(EAGAIN);
#endif
#ifdef PLATFORM_WIN32
	return c == SOCKERR(EWOULDBLOCK) || c != SOCKERR(ENOTCONN);
#endif
}


I hope that will fix the problem.

[Updated on: Wed, 18 July 2012 02:26]

Report message to a moderator

Re: XML Rpc client will halt when server is not running [message #36619 is a reply to message #36611] Thu, 21 June 2012 05:21 Go to previous messageGo to next message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
Here is full XML RPC Server & Client Code

Server:
#include <conio.h>
#include <Core/Core.h>
#include <Core/XMLRpc/XMLRpc.h>

using namespace Upp;

XMLRPC_METHOD( Compute ) {
	double a, b;
	Upp::String arithmeticOperator;
	rpc >> a >> arithmeticOperator >> b;
	LOG( Upp::Format("Request: %nf %s %nf", a, arithmeticOperator, b) );

	if( arithmeticOperator.GetCount() == 1 ) {
		switch( *arithmeticOperator ) {
			case '+': {
				rpc << a + b;
				break;
			}
			case '-': {
				rpc << a - b;
				break;
			}
			case '/': {
				if( b == 0 ) {
					rpc << Upp::ErrorValue("division by zero");
				}
				else {
					rpc << a / b;
				}
				break;
			}
			case '*': {
				rpc << a * b;
				break;
			}
		}
	}
	else {
		rpc << Upp::ErrorValue("unknown operator");
	}
}

XMLRPC_METHOD( GetServerTime ) {
	LOG( "Request: GetServerTime" );
	rpc << Upp::GetSysTime();
}

int main() {
	TcpSocket rpc;
	int port = 1234;
	
	if( !rpc.Listen(port,5) ) {
		return false;
	}

	while( true ) {
		if( _kbhit() ) {
			if( _getch() == 27 ){
				break;
			}
		}

		TcpSocket http;
		http.Timeout(1000);
		if( http.Accept(rpc) ) {
			XmlRpcPerform(http,NULL);
		}
	}

	return 0;
}



Client:
#include <Core/Core.h>
#include <Core/XMLRpc/XMLRpc.h>

using namespace Upp;

namespace Upp { 
	extern bool HttpRequest_Trace__;
}

void Compute( double a, Upp::String arithmeticOperator, double b );

int main() {
	Time serverTime;
	SetDateFormat( "%4d-%02d-%02d" );
	XmlRpcRequest call( "127.0.0.1:1234" );
	if( call("GetServerTime") >> serverTime ) {
		LOG( "Server Time = " << serverTime );
	}
	else {
		LOG( Upp::Format("Error: %s", call.GetError()) );
	}

	Compute( 12, "+", 12 );
	Compute( 12, "*", 12 );
	Compute( 12, "+56", 12 );
	Compute( 12, "/", 0 );

	return 0;
}

void Compute( double a, Upp::String arithmeticOperator, double b ) {
	double result = 0;
	XmlRpcRequest call( "127.0.0.1:1234" );
	if( call("Compute", a, arithmeticOperator, b) >> result ) {
		LOG( Upp::Format("%f %s %f = %f", a, arithmeticOperator, b, result) );
	}
	else {
		LOG( Upp::Format("Error: %s", call.GetError()) );
	}
}
Re: XML Rpc client will halt when server is not running [message #36620 is a reply to message #36619] Thu, 21 June 2012 09:09 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
This is wrong solution. Win32 regulary returns WSAENOTCONN when connection is in progress.

I guess the real problem is that we are here simulating blocking sockets using non-blocking behaviour. Win32 seems to give up connect in blocking mode after 21 seconds. So the correct solution is perhaps to simulate this special timeout as well - done, please check.

(You can also decrease the timeout using Timeout).

Mirek
Re: XML Rpc client will halt when server is not running [message #36624 is a reply to message #36620] Thu, 21 June 2012 17:16 Go to previous message
kasome is currently offline  kasome
Messages: 78
Registered: July 2008
Location: Taiwan
Member
i try the latest u++ r5074, and it works well now, not halt anymore.

but i still can't use Timeout nor RequestTimeout, i.e.

 XmlRpcRequest call( "127.0.0.1:1234" );
 call.Timeout(1000);        // VS2005 compile error
 call.RequestTimeout(1000); // VS2005 compile error


because XmlRpcRequest is private inheritance from HttpRequest,

how about change

 class XmlRpcReques : HttpRequest


to

 class XmlRpcReques : public HttpRequest ?




and thanks. Smile

[Updated on: Sun, 24 June 2012 04:30]

Report message to a moderator

Previous Topic: What`s the corect way to use TimingInspector?
Next Topic: How to add 6 months to a date?
Goto Forum:
  


Current Time: Fri Apr 19 04:30:57 CEST 2024

Total time taken to generate the page: 0.68295 seconds