I integrated xmlrpc into a c++ game engine (long story) and have it working for the most part. I took the build in the zip (0.7) and then went through and applied several patches including the better error handling.
It is all working pretty well like I said but I am getting an error every once in a while.
I was wondering if anyone else was getting this:
Error in XmlRpcClient::writeRequest: write error (error 10057 - Unknown error).
I will issue a command and get a response and have it work and then every once in a while I get this error on the same command. It seems to happen more often when I am running the server on the same machine (localhost) as the client.
The client is where the error is occurring. The server was writing by other people in python, but appears to not be where the problem is happening from what I can understand of the error.
Any ideas on why this may be happening would be great I understand it is hard to know exactly without know what exact version and I have been thinking about merging with what is on cvs as there are probably numerous fixes that where not in patch form, I just worry there may have been bugs introduced as well since it appears there is not stable tested releases anymore. Especially with new features like ssl integrated now that I don't really care about.
Also the key in my testing I figured out is that it happens way more often on localhost, but still does happen when running the server on another machine on the same network. Also there is a good chunk of bandwidth being taken up by UDP Multicast packets (over 100 a second possibly) but these are of course on different ports and over a different protocol.
Any help would be great I can even upload the code I am running if need be. Also if I have assurance that it would be best to get the latest cvs build then I may merge with it and test again.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Have you checked that all reads and writes check that all requested bytes have been read/written, and then keep trying until all bytes have been read/written?
This is a common error in network programming and can cause transient errors. A large percentage of the time, the operating system will complete the entire transaction on the first time, but not always. In pseudo code:
No I haven't checked this, but wouldn't the library handle this for me and then store everything in variables? I suppose you could be referring to the other network data not handled by xmlrpc. I will do some test to see if it happens when the other data isn't coming in.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It does still happen if I have no other data being received. So I guess I then still wonder shouldn't this be handled by the library? Although this may be a bug in it to look for. If it isn't and it is in some way in which I am using it which I don't think it is. I will definitely look more at my integration code to see if there could be any place this is happening, but I mostly just use the library and store the values in variables which.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I do not know if you still have this issue. It that is the case, a few infos about the appliation 'architecture' (multithreading?), system and so on will be really helpful…
Quique
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It was integrated into Torque3D a game Engine. I am not positive what exactly is multithreaded, but I can look at it. As far as how I integrated this library I simply added the files as a visual studio project to compile a dll and as a dependency for Torque3D. I then created a class that Inherits from SimObject which is a very base class in the engine. As an example FileObject, StreamObject, TCPObject all inherit from SimObject. I then just added some rappers for methods like connect that simply create an XMLRpcClient and pass it the IP and the class stores a reference the the object created. Disconnect simply calls delete on the XMLRPCClient created (if not null of course). And there are several other rappers like isFualt, execute… and I just pass them what they need.
I know that doesn't help you much about what is multithreaded, but hopefully gives you a little better idea about how it is implemented. I really didn't have to do a lot to get it working which is why I used this library it was very simple and to the point and didn't have a bunch of other stuff I didn't need. I pretty much let the library handle everything. I see what you are saying about multithreading though, cause if the XmlRpcClient object doesn't get its execution time it may not get all the info that comes across the network. I will track down what is multithreaded and reply again on here.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Multithreading is used for audio&video streaming (includes sound loading), DNS lookups, and the rest happens in the main thread which is where my code executes.
The only other thing that runs in at least one other thread but isn't really part of the engine it can just has support for it is PhysX, but I don't use it at all.
Hope that helps give you some more info.
As for making it multithreaded I would be using standard C++, but may have some help from some classes:
"Also, there's a few threaded data structures there that exclusively use lock-free synchronization through atomic instructions, a framework for concurrent reference counting, and a number of classes to offload stream I/O to worker threads."
Since what I am doing is happening in the main thread it doesn't seem like that should be the problem, it will just slow down everything else in the engine until it gets a reply which should be pretty quick. Also it seems like the longer it takes the less this bug pops up so I don't think it is an issue with threading.
Feel free to comment with this new info and thanks for the input thus far!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I went back to your first message. There, you mentioned the error code. In the source code from XmlRpc++, this error is only possible in file XmlRpcClient.cpp, function XmlRpcClient::writeRequest
if ( ! XmlRpcSocket::nbWrite(this->getfd(), _request, &_bytesWritten)) {
XmlRpcUtil::error("Error in XmlRpcClient::writeRequest: write error (%s).",XmlRpcSocket::getErrorMsg().c_str());
The error code you got is 10057L, and according to WinError.h, it is WSAENOTCONN: "A request to send or receive data was disallowed because the socket is not connected (…)"
I know, it is not very specific, but so are windows error codes.
I can imagine many possible reasons why it happened, but I need more inputs from you.
An important input is a complete "log" from XmlRpc++. To do that, use the following code:
XmlRpc::setVerbosity(5);
Use this function before calling the client interface that produces the error.
My usual suspect for this kind of error? a full receiving at the server side
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok I will call that before trying to reproduce the error and post the results.
Just one clarification though when you say "a full receiving at the server side" do you mean the server not getting every packet? and if so is it because it was never sent to the server or because the server didn't receive everything it should be (bug on the server end or on the client end)?
Thank you very much for your help!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Seems when I set the verbosity to 5 I get an assertion about the buffer not being big enough. Seems it is 1024. I haven't messed with va_start or vsnprintf much but is there any way I can do similar work in XmlRpcUtil::log using a dynamic buffer like String or something or an easy way to pass the arguments to printf?
I integrated it into Torque 3D, a game engine and everything is output to the console using Con::printf which is pretty much the same, if not the same, as printf. I just made my own error handler which calls Con::printf(msg), but it could call it and pass it the same thing XmlRpcUtil::log gets.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
XmlRpcSocket::nbWrite: send/write returned 262.
XmlRpcClient::writeRequest: wrote 262 of 262 bytes.
XmlRpcSocket::nbRead: read/recv returned -1.
Error in XmlRpcClient::readHeader: error while reading header (error 0 - No error) on fd 20880.
getList xml-rpc call never got a response while checking mission component start functions.
There may be some extra errors that I printed within my own code when a I don't get a response, so if you see some extra stuff that is what that is. Also I noticed once setting the verbosity to 5 the server showed some errors. It is written by another party in Python. I would put those here, but not sure if I can for NDA reasons.
Hope this helps you help me :)
To me it looks like it is trying to send data (which I think it sends), but the server never responds so it doesn't think the data got there. Also I was unable to reproduce the issue for a while until I made sure both network cards (2 on the machine, but only using one) where enabled and both the server and the client are running on the same machine.
Let me know if you need any more info. Thanks for the help thus far!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It looks like the head on svn has a lot of changes. Are they all solid changes? Should I just update everything to the head? or is it a work in progress?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I integrated xmlrpc into a c++ game engine (long story) and have it working for the most part. I took the build in the zip (0.7) and then went through and applied several patches including the better error handling.
It is all working pretty well like I said but I am getting an error every once in a while.
I was wondering if anyone else was getting this:
Error in XmlRpcClient::writeRequest: write error (error 10057 - Unknown error).
I will issue a command and get a response and have it work and then every once in a while I get this error on the same command. It seems to happen more often when I am running the server on the same machine (localhost) as the client.
The client is where the error is occurring. The server was writing by other people in python, but appears to not be where the problem is happening from what I can understand of the error.
Any ideas on why this may be happening would be great I understand it is hard to know exactly without know what exact version and I have been thinking about merging with what is on cvs as there are probably numerous fixes that where not in patch form, I just worry there may have been bugs introduced as well since it appears there is not stable tested releases anymore. Especially with new features like ssl integrated now that I don't really care about.
Also the key in my testing I figured out is that it happens way more often on localhost, but still does happen when running the server on another machine on the same network. Also there is a good chunk of bandwidth being taken up by UDP Multicast packets (over 100 a second possibly) but these are of course on different ports and over a different protocol.
Any help would be great I can even upload the code I am running if need be. Also if I have assurance that it would be best to get the latest cvs build then I may merge with it and test again.
Have you checked that all reads and writes check that all requested bytes have been read/written, and then keep trying until all bytes have been read/written?
This is a common error in network programming and can cause transient errors. A large percentage of the time, the operating system will complete the entire transaction on the first time, but not always. In pseudo code:
bytesRead = 0
bytesLeft = bytesRequested
bufPtr = buffer
while (byesRead < bytesRequested) {
rc = read(port, bufPtr, bytesLeft)
if (rc > 0) {
bytesRead += rc
bufPtr += rc
bytesLeft -= rc
} else {
ERROR
}
}
No I haven't checked this, but wouldn't the library handle this for me and then store everything in variables? I suppose you could be referring to the other network data not handled by xmlrpc. I will do some test to see if it happens when the other data isn't coming in.
It does still happen if I have no other data being received. So I guess I then still wonder shouldn't this be handled by the library? Although this may be a bug in it to look for. If it isn't and it is in some way in which I am using it which I don't think it is. I will definitely look more at my integration code to see if there could be any place this is happening, but I mostly just use the library and store the values in variables which.
I do not know if you still have this issue. It that is the case, a few infos about the appliation 'architecture' (multithreading?), system and so on will be really helpful…
Quique
It was integrated into Torque3D a game Engine. I am not positive what exactly is multithreaded, but I can look at it. As far as how I integrated this library I simply added the files as a visual studio project to compile a dll and as a dependency for Torque3D. I then created a class that Inherits from SimObject which is a very base class in the engine. As an example FileObject, StreamObject, TCPObject all inherit from SimObject. I then just added some rappers for methods like connect that simply create an XMLRpcClient and pass it the IP and the class stores a reference the the object created. Disconnect simply calls delete on the XMLRPCClient created (if not null of course). And there are several other rappers like isFualt, execute… and I just pass them what they need.
I know that doesn't help you much about what is multithreaded, but hopefully gives you a little better idea about how it is implemented. I really didn't have to do a lot to get it working which is why I used this library it was very simple and to the point and didn't have a bunch of other stuff I didn't need. I pretty much let the library handle everything. I see what you are saying about multithreading though, cause if the XmlRpcClient object doesn't get its execution time it may not get all the info that comes across the network. I will track down what is multithreaded and reply again on here.
So there isn't much threading going on in T3D and none within the object I use as a rapper for the XmlRpcClient object.
From what I gathered from people's response on http://www.torquepowered.com/community/forums/viewthread/109459/1#comment-717737 it is private so you probably won't be able to access it unless you have a GarageGames account and Torque 3D.
Multithreading is used for audio&video streaming (includes sound loading), DNS lookups, and the rest happens in the main thread which is where my code executes.
The only other thing that runs in at least one other thread but isn't really part of the engine it can just has support for it is PhysX, but I don't use it at all.
Hope that helps give you some more info.
As for making it multithreaded I would be using standard C++, but may have some help from some classes:
"Also, there's a few threaded data structures there that exclusively use lock-free synchronization through atomic instructions, a framework for concurrent reference counting, and a number of classes to offload stream I/O to worker threads."
Since what I am doing is happening in the main thread it doesn't seem like that should be the problem, it will just slow down everything else in the engine until it gets a reply which should be pretty quick. Also it seems like the longer it takes the less this bug pops up so I don't think it is an issue with threading.
Feel free to comment with this new info and thanks for the input thus far!
Hi,
I went back to your first message. There, you mentioned the error code. In the source code from XmlRpc++, this error is only possible in file XmlRpcClient.cpp, function XmlRpcClient::writeRequest
The error code you got is 10057L, and according to WinError.h, it is WSAENOTCONN: "A request to send or receive data was disallowed because the socket is not connected (…)"
I know, it is not very specific, but so are windows error codes.
I can imagine many possible reasons why it happened, but I need more inputs from you.
An important input is a complete "log" from XmlRpc++. To do that, use the following code:
XmlRpc::setVerbosity(5);
Use this function before calling the client interface that produces the error.
My usual suspect for this kind of error? a full receiving at the server side
Ok I will call that before trying to reproduce the error and post the results.
Just one clarification though when you say "a full receiving at the server side" do you mean the server not getting every packet? and if so is it because it was never sent to the server or because the server didn't receive everything it should be (bug on the server end or on the client end)?
Thank you very much for your help!
Seems when I set the verbosity to 5 I get an assertion about the buffer not being big enough. Seems it is 1024. I haven't messed with va_start or vsnprintf much but is there any way I can do similar work in XmlRpcUtil::log using a dynamic buffer like String or something or an easy way to pass the arguments to printf?
I integrated it into Torque 3D, a game engine and everything is output to the console using Con::printf which is pretty much the same, if not the same, as printf. I just made my own error handler which calls Con::printf(msg), but it could call it and pass it the same thing XmlRpcUtil::log gets.
Ok so I got everything working (just passed the argument list off to vprintf so there wasn't the buffer issue) and here is what was logged:
User-Agent: XMLRPC++ 0.7
Host: localhost:9700
Content-Type: text/xml
Content-length: 146
<?xml version="1.0"?>
<methodCall><methodName>getList</methodName>
<params><param><value>start functions</value></param></params></methodCall>
XmlRpcSocket::nbWrite: send/write returned 262.
XmlRpcClient::writeRequest: wrote 262 of 262 bytes.
XmlRpcSocket::nbRead: read/recv returned -1.
XmlRpcClient::readHeader: re-trying connection
XmlRpcSource::close: closing socket 20880.
XmlRpcSocket::close: fd 20880.
XmlRpcSource::close: done closing socket 20880.
XmlRpcClient::doConnect: fd 20880.
XmlRpcClient::writeRequest (attempt 2):
POST /RPC2 HTTP/1.1
User-Agent: XMLRPC++ 0.7
Host: localhost:9700
Content-Type: text/xml
Content-length: 146
<?xml version="1.0"?>
<methodCall><methodName>getList</methodName>
<params><param><value>start functions</value></param></params></methodCall>
XmlRpcSocket::nbWrite: send/write returned 262.
XmlRpcClient::writeRequest: wrote 262 of 262 bytes.
XmlRpcSocket::nbRead: read/recv returned -1.
Error in XmlRpcClient::readHeader: error while reading header (error 0 - No error) on fd 20880.
getList xml-rpc call never got a response while checking mission component start functions.
There may be some extra errors that I printed within my own code when a I don't get a response, so if you see some extra stuff that is what that is. Also I noticed once setting the verbosity to 5 the server showed some errors. It is written by another party in Python. I would put those here, but not sure if I can for NDA reasons.
Hope this helps you help me :)
To me it looks like it is trying to send data (which I think it sends), but the server never responds so it doesn't think the data got there. Also I was unable to reproduce the issue for a while until I made sure both network cards (2 on the machine, but only using one) where enabled and both the server and the client are running on the same machine.
Let me know if you need any more info. Thanks for the help thus far!
Hi,
you might also check out this fix:
http://git.sip-router.org/cgi-bin/gitweb.cgi?p=sems;a=commitdiff;h=312d8c9010279ba931a99cf660bba4a6a1da6f8d
- if the write fails with a non-fatal error, the connection should stay in the writing state, and continue writing when the socket becomes writable again.
BR
Stefan
It looks like the head on svn has a lot of changes. Are they all solid changes? Should I just update everything to the head? or is it a work in progress?