I’m attempting to send a .proto message from an iPhone application to a Java server via a socket connection. However so far I’m running into an issue when it comes to the server receiving the data; it only seems to process it after the client connection has been terminated. This points to me that the data is getting sent, but the server is keeping its inputstream open and waiting for more data. Would anyone know how I might go about solving this? The current code (or at least the relevant parts) is as follows:
iPhone:
Person *person = [[[[Person builder] setId:1] setName:@"Bob"] build];
RequestWrapper *request = [[[RequestWrapper builder] setPerson:person] build];
NSData *data = [request data];
AsyncSocket *socket = [[AsyncSocket alloc] initWithDelegate:self];
if (![socket connectToHost:@"192.168.0.6" onPort:6666 error:nil]){
[self updateLabel:@"Problem connecting to socket!"];
} else {
[self updateLabel:@"Sending data to server..."];
[socket writeData:data withTimeout:-1 tag:0];
[self updateLabel:@"Data sent, disconnecting"];
//[socket disconnect];
}
Java:
try {
RequestWrapper wrapper = RequestWrapper.parseFrom(socket.getInputStream());
Person person = wrapper.getPerson();
if (person != null) {
System.out.println("Persons name is " + person.getName());
socket.close();
}
On running this, it seems to hang on the line where the RequestWrapper is processing the inputStream. I did try replacing the socket writedata method with:
[request writeToOutputStream:[socket getCFWriteStream]];
(here I’m calling the gpb to write to the output stream, instead of writing the data generated to the output stream)
Which I thought might work, however I get an error claiming that the “Protocol message contained an invalid tag (zero)”. I’m fairly certain that it doesn’t contain an invalid tag as the message works when sending it via the writedata method.
Any help on the matter would be greatly appreciated!
Cheers!
Dan
(EDIT: I should mention, I am using the metasyntactic gpb code; and the cocoaasyncsocket implementation)
Finally I managed to solve it!! It’s embarrassing how simple it was once I stopped caring about the GPB way of doing it. The C++ code I used is:
and then on the Java end I just kept the
line and it works a treat! All I end up doing is sending the size of the data before the data itself and the GPB method on the Java end works out the rest!
One major problem I had was actually converting the size of the data to send, from an int to NSData, and having it send across the network correctly. The way I was advised of doing it was
NSData *size = [NSData dataWithBytes:&s length:sizeof(s)];
However whenever I sent that across as data, it would seem to send the first byte, along with 3 “0” bytes. This caused havoc with GPB because if it receives a 0 byte at any point it throws an exception thinking the code is corrupt (my guess). Seeing as I never looked at the actual bytes coming across and analysing them until trying to do it a different way today, I am a bit gutted as I could have figured out that this was the issue a while ago. After some experimenting around with it, I gathered that the ‘sizeof’ method was the problem so I removed it. Currently I have just put a ‘1’ instead of the actual size, which
seems to only return 1 byte when sending the data file across the network; although I’m not sure thats going to be an ‘ideal’ solution (although the message size should only be in 1 byte anyway) – if anyone could advise me why this sizeof() is causing an issue, it would be appreciated 🙂
Points should really go to Luke Steffen who helped me with this on the cocoaasyncsocket google group despite my idiocy – so again, thanks Luke!