String data from serial fails to be parsed as JSON - android
I am building a device that can communicate between a vehicle ECU, Arduino, and Android device. The end goal is to get information from the car to the user's phone.
I currently have the following Arduino code that collects vehicle data via the OBD-II port and sends over the serial as JSON:
#include <Wire.h>
#include <OBD.h>
COBDI2C obd;
char vin[64];
int distance;
int velocity;
int runtime;
String json;
void setup() {
Serial.begin(9600);
obd.begin();
while(!obd.init());
}
void loop() {
obd.getVIN(vin, sizeof(vin));
delay(100);
obd.readPID(PID_DISTANCE, distance);
delay(100);
obd.readPID(PID_SPEED, velocity);
delay(100);
obd.readPID(PID_RUNTIME, runtime);
delay(100);
json = "{\"vin\":\"";
json.concat(vin);
json.concat("\",\"distance\":\"");
json.concat(distance);
json.concat("\",\"speed\":\"");
json.concat(velocity);
json.concat("\",\"runtime\":\"");
json.concat(runtime);
json.concat("\"}");
Serial.print(json);
delay(5000);
}
This would print a string such as "{\"vin\":\"3VWJM71K89M02\",\"distance\": \"19478\",\"speed\":\"0\",\"runtime\":\"216\"}" over a USB connection to an Android device. I have a method that is called on the Android device when USB activity occurs:
public void onReceivedData(byte[] result) {
String dataStr;
try {
dataStr = new String(result, "UTF-8");
dataStr = dataStr.replaceAll("[\\n\\r\\s]+", "");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
driveData = new JSONObject(dataStr);
updateVehicle(driveData);
} catch(JSONException e) {
e.printStackTrace();
}
}
For some reason, the resulting byte array can be converted into a string with no errors, yet is oddly populated with random line breaks and whitespaces, which is why I used replaceAll() to remove these. When I try to create a JSONObject from the string (using the org.json library) I get errors. However, when I append the original string to a textView, I get something that appears to be very valid JSON:
{"vin":"3VWJM71K89M02","distance":"19478","speed":"0","runtime":"216"}
Next, I tried constructing a JSONObject using the exact string constructed on the Arduino earlier, such as so:
try {
driveData = new JSONObject("{\"vin\":\"3VWJM71K89M02\",\"distance\": \"19478\",\"speed\":\"0\",\"runtime\":\"216\"}");
updateVehicle(driveData);
} catch(JSONException e) {
e.printStackTrace();
}
This threw me no errors at all. So what am I doing wrong that the original data sent via USB is not as valid as actual data that arrives?
Update:
By request I have some error codes from the Android device. Unfortunately, it seems like a chain reaction, so I am providing some of the first ones:
org.json.JSONException: Unterminated string at character 4 of {"vi
org.json.JSONException: End of character input at character 0 of
org.json.JSONException: Value n" of typejava.lang.String cannot be converted to JSONObject
org.json.JSONException: End of character input at character 0 of
org.json.JSONException: Unterminated string at character 7 of "3VMJM7
org.json.JSONException: ...
As gre_gor mentioned in the comments, the event receiving the USB data was not capturing the entire message from the Arduino in a single call. I found that if you keep a running string of the all the USB data and check that string for JSON syntax each call, you eventually get a valid JSON object. Then just reset the string and keep listening.
So, my new code would look like:
public String usbStr = "";
public JSONObject driveData;
...
public void onReceivedData(byte[] result) {
String dataStr;
try {
dataStr = new String(result, "UTF-8");
dataStr = dataStr.replaceAll("[\\n\\r\\s]+", "");
usbStr = usbStr.concat(dataStr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
driveData = new JSONObject(dataStr);
usbStr = "";
updateVehicle(driveData);
} catch(JSONException e) {
e.printStackTrace();
}
}
Related
QTcpServer with android client unable to print or use data received from client
I am developing Client-Server application in C++ using Qt framework, but the clients can be android phones and computers(Qt client app) Now i'm having troubles to handle Reception of data on the server side; the server is not receiving data properly. First, I got things working nicely between the server(Qt app) and the client(Qt app) using these methods for sending and receiving: The size of the message is kept at the beginning of the packet to help check whether the whole message is received or not. This is the method to send message to the clients void Server::send(const QString &message) { QByteArray paquet; QDataStream out(&paquet, QIODevice::WriteOnly); out << (quint16) 0; // just put 0 at the head of the paquet to reserve place to put the size of the message out << message; // adding the message out.device()->seek(0); // coming back to the head of the paquet out << (quint16) (paquet.size() - sizeof(quint16)); // replace the 0 value by the real size clientSocket->write(paquet); //sending... } This slot is called every time a single paquet is received. void Server::dataReceived() { forever { // 1 : a packet has arrived from any client // getting the socket of that client (recherche du QTcpSocket du client) QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); if (socket == 0) return; QDataStream in(socket); if (dataSize == 0) // if we don't know the size of data we are suppose to receive... { if (socket->bytesAvailable() < (int)sizeof(quint16)) // we haven't yet receive the size of the data completly then return... return; in >> dataSize; // now we know the amount of data we should get } if (socket->bytesAvailable() < dataSize) return; // Here we are sure we got the whole data then we can startreadind QString message; in >> message; //Processing.... dataSize = 0; // re-initialize for the coming data } } This is working well when the server is talking with the Qt app Client, because the same methods are used there, and the size of quint16 will remain the same hover it doesn't work with android client, then i tried another way in which i wanted to ignore the size of the message sent, but format the message in a way such that i can know where it starts and where it ends, then with some controls i can get it however i'm stuck here, cause the data read doesn't contain anything when printed, but his size has a value(which even vary according to the amount of text the client send)! void Server::dataReceived() // a packet is received! { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); if (socket == 0) return; QByteArray data= socket->readAll(); //reading all data available QString message(data) qDebug() << data; // this prints nothing! qDebug() << data.size();// But this prints a non null number, wich means we got something, and that number varies according to the amount of text sent! qDebug() << message; // this also prints notghing! } PS: it's not working even for the Qt app Client. Can you help me find out what's wrong, i'm a bit confused how the tcp protocol is handling the data, and if you could and also advise me a good way for doing this. here is the android class I made for the purpose class QTcpSocket implements Runnable { private String ip=""; private int port; private Socket socket; private PrintWriter printWriter; private DataOutputStream dataOutputStream; private DataInputStream dataInputStream; public QTcpSocket(String ip, int port) { this.ip = ip; this.port = port; } public void setIp(String ip) { this.ip = ip; } public String getIp() { return this.ip; } public void setPort(int port) { this.port = port; } public void run() { try { socket = new Socket(this.ip, this.port); dataOutputStream = new DataOutputStream( socket.getOutputStream() ); dataInputStream = new DataInputStream(socket.getInputStream()); String response = dataInputStream.readUTF(); dataOutputStream.writeUTF("Hello server!"); } catch (IOException e) { e.printStackTrace(); } } public void sendMessage(String message) { try { dataOutputStream.writeUTF(message); }catch (IOException e) { e.printStackTrace(); } } public void disconnect() { try { printWriter.flush(); printWriter.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } public boolean isClosed() { return socket.isClosed(); } }
Replace in 'data' all bytes with value 0 by value 20 and print again. I think you see nothing printed because the first byte is 0. You could also replace with 'X'. Did you already replace writeUTF() by write() ? 20 is the space character. But then you also see nothing printed so better use a X char. Strings get printed until a \0 char (which indicates the end of a string) is met. Because nothing was printed i supposed one right at the beginning. So writeUTF causes that leading 0. I could only explain that if all chars had doubled. What was the first char you sent? But now: send size-of-message first so it equals your qt client.
Weird JSON encoding issue on Android 4.1.2
I have an issue on Android 4.1.2 where a JSON object given to us by our REST API gets encoded weirdly when sending back. This is the snippet of json I'm getting: "cost":{ "amount": 0, "currency": "GBP" } I'm wanting to pretty much just pass this particular snippet back the same way (modifying other parts of the json), but this is what I get on Android 4.1.2: "cost":"{amount=0, currency=GBP}" The function I believe is causing this weird encoding is here: private StringEntity getEntityForRequest(final Payment payment, final PaymentDelegate delegate) { JSONObject json = new JSONObject(); MyApplication.getContext().addApplicationInformationToJSONObject(json); StringEntity entity = null; try { entity = new StringEntity(json.toString(), "UTF-8"); } catch (UnsupportedEncodingException e1) { payment.markAsFailed("Reservation failed, data returned not expected."); save(payment); if (delegate != null) { delegate.onFailure(new MyError(MyError.DEFAULT_STATUS, MyError.DEFAULT_TYPE, "Payment error", "Error during reservation")); } } return entity; } This is the addApplicationIformationToJSONObject function: /** * Adds system information to a JSON object. */ public void addApplicationInformationToJSONObject(JSONObject json) { try { try { json.put("app_version", getPackageManager().getPackageInfo(getPackageName(), 0).versionName); } catch (NameNotFoundException e) { json.put("app_version", "Unknown"); } json.put("device", getDeviceName()); json.put("os_type", "android"); json.put("os_version", String.format("%d", Build.VERSION.SDK_INT)); json.put("device_id", Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID)); } catch (JSONException e) { MyLog.e("MyApplication", "Error when adding system information to JSON"); } } What's causing this weird encoding? How can I modify the code to avoid issues like this?
Found a solution. It seems older version interprets that cost snippet as a string rather than a JSONObject. Doing this seems to solve the issue: ticketObject.remove("cost"); ticketObject.put("cost", new JSONObject(getCost()));
Threads, atomic boolean, synchronized design considerations for a method that has to wait for a result
My code is starting to get a bit hard to debug which leads me to believe that my design choices are not ideal. I am a novice Android programming and would love some help with streamlining the design for optimum operation. Intro I am writing an application that uses rfcomm interface to transfer data between a client and server device. The client needs to request certain things from the server using a specific key, then it needs to wait until the server sends the result back. Current Design A button press triggers a request for information from the server. A new thread is started which performs the request. A key which is a unique integer is converted to a byte array and sent to the server. Thread has a while loop that is waiting for a specific boolean to flip from false to true indicating a response back from the server. Information is received on the server side. Server uses key to identify what to do next. server starts a thread to run some query and gets a jsonString back as a result. Server sends jsonstring converted to byte array prepended with the same identifying key back to the client. Client reads message, and sends the byte array to a handling method based on the identifying key. Handling method stores jsonString to a class variable and then flips the boolean to let the other thread know that the value it was waiting on has been set. Json string is converted to object on the client side. Something is done with that object. This code currently correctly sends info to the server, server correctly does search and gets a valid json string result. However, the issue occurs when the server writes its results make to the client. I am getting 20 messages instead of one and none match the search key... My questions Am I doing things in an efficient way design wise? Can I benefit from using synchronized keyword or and Atomic Boolean to make my code more thread safe? How would I go about implementing it? Is there a max length for converting strings to byte array? Maybe the code is trying to break up the sending for me and that's why I'm getting 20 different results? Relevant code public class ClientSpokesmanClass { private final int searchKey = 2222222; //set the key to some int. private boolean pendingSearchResults = false; List<Place> places = new ArrayList<Place>(); private final Handler handler = new Handler(){ #Override public void handleMessage(Message msg){ switch(msg.what) { ... case MESSAGE_READ: //Message received from server readAndDistribute(msg.arg1, msg.obj); break; ... } } }; public List<Place> getPlacesFromServer(String query){ //ask server for search results requestSearchFromServer(query); //just wait for them... while (pendingSearchResults){ //just waiting } return places; } private void requestSearchFromConnectedDevice(String query) { if (mBluetoothState == STATE_CONNECTED){ byte[] bites = new byte[4]; bites = ByteBuffer.wrap(bites).putInt(searchKey).array(); byte[] stringBytes = null; try { stringBytes = query.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.e(TAG, "unsupported encoding", e); } int keyLength = bites.length; int stringLength = stringBytes.length; byte[] combined = new byte[keyLength+stringLength]; System.arraycopy(bites, 0, combined, 0, keyLength); System.arraycopy(stringBytes, 0, combined, keyLength, stringLength); mBluetoothService.write(combined); } pendingSearchResults = true; } private void receiveSearchResults(byte[] bites){ String jsonString = ""; PlacesJSONParser parser = new PlacesJSONParser(); try { jsonString = new String(bites, "UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.e(TAG, "unsupported encoding", e); } if (D) Log.d(TAG, "Json string we got is "+jsonString); try { places = parser.parse(new JSONObject(jsonString)); } catch (JSONException e) { // TODO Auto-generated catch block Log.e(TAG, "JSON exception", e); } pendingSearchResults = false; } /** * Reads come here first. Then, based on the key prepended to them, * they then go to other methods for further work. * #param bytes * #param buffer */ private synchronized void readAndDistribute(int bytes, Object buffer){ byte[] buff = (byte[]) buffer; int key = ByteBuffer.wrap(Arrays.copyOfRange(buff, 0, 4)).getInt(); if (key == searchKey){ receiveSearchResults(Arrays.copyOfRange(buff, 4, bytes)); }else{ //do something else } } } . public class ClientUI extends Activity { ... onQueryTextSubmit(String query){ final String queryFinal = query; Thread thread = new Thread(){ public void run() { places = ClientSpokesmanClass.getPlacesFromServer(query); doSomethingWithPlaces(); } }; thread.start(); } } . public class ServerReceive { private searchKey = 2222222; ... //code that handles messages, reads key, and then runs doSearchAndWriteResults() ... private synchronized void doSearchAndWriteResults(byte[] bites){ if (D) Log.d(TAG, "+++writeSearchResults"); //Initialize query and placesString String query = null; String placesString; //Convert byte array to the query string try { query = new String(bites, "UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.e(TAG, "unsupported encoding",e); } //if the string was converted successfully... if (query != null){ //Run the places query and set the json string to placesString if (D) Log.d(TAG, "query is "+query); PlacesProvider placeProvider = new PlacesProvider(); placesString = placeProvider.getPlacesString(query); } //initialize a bite array byte[] stringBytes = null; try { //convert jsonString to byte array stringBytes = placesString.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.e(TAG, "unsupported encoding",e); } //Put the search key to a byte array. I am using this key on the client side //to confirm that we are reading searchResults and not some other type of write. byte[] bite = new byte[4]; bite = ByteBuffer.wrap(bite).putInt(searchKey).array(); //Get the lengths of the two byte arrays int keyLength = bite.length; int stringLength = stringBytes.length; //combine the byte arrays for sending byte[] combined = new byte[keyLength+stringLength]; System.arraycopy(bite, 0, combined, 0, keyLength); System.arraycopy(stringBytes, 0, combined, keyLength, stringLength); if (D) Log.d(TAG, "Actually writing things here..."); //send the byte arrrays over rfcomm mBluetoothService.write(combined); } }
Take a look at https://github.com/gettyimages/connect_sdk_java. Specifically, at the test application. It performs a search using an AsyncTask and the private class notifies the UI via onPostExecute. Hopefully, this will get you further along.
Strange behaviour when receiving data
I'm developing an Android app that requires me to get some data from the server, this data is comes as JSON data, I have to receive like 7 JSON Objects, I'm using regular socket programming to get this data, and I get it by launching a thread that will wait for a data to come from the server. I'm using the following method: public String getServerRespons() throws JSONException { String responseLine, server_response = null_string; try { input = new BufferedReader(new InputStreamReader( socket.getInputStream())); } catch (IOException e) { } int count = 0; boolean first = true; try { while (true) { if((responseLine = input.readLine()) == null){ break; } first = false; server_response = server_response + responseLine; // // some processing to make sure it's a valid JSON // if(count == 0){ // related to the Processing Lines result System.out.println(server_response); return response; // when commenting that line everything is ok } } } catch (IOException e) { Login.errorMessage.setText(conn_err); } return null; } With that way i got like only two or three JSON Objects of the seven ones. BUT, when commenting the return Line and let it completes with the receiving process I got all the seven Objects efficiently and each Object is separated which makes me make sure that the processing i made to validate the JSON is going so well.
I think int count is always 0 in your example so the return statement is always hit.
Data being lost between Android device and python server using TCP
I'm somewhat new to network programming and am having some trouble. I am creating a JSON object on an Android device, connecting to a python server via TCP, and sending the JSON string. The connection gets accepted, but I keep losing the end of the string, so json.loads(json_string) is failing. Here is the relevant Android code: private class Worker implements Runnable { #Override public void run() { //create the network socket try { socket = new Socket(address, 4242); Log.i(TAG, "timeout: " + socket.getSoTimeout()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } packets = new ArrayList<JSONObject>(); for (jobs.moveToFirst(); jobs.isAfterLast() == false; jobs.moveToNext()) { String jobName = jobs.getString(jobs.getColumnIndex(JobMetaData.JobTableMetaData.JOB)); Uri.Builder updated = new Uri.Builder(); updated.scheme("content"); updated.authority(JobMetaData.AUTHORITY); updated.appendPath(jobName); updated.appendPath("member"); updated.appendPath(JobMetaData.MemberTableMetaData.CHANGED); updated.appendPath("true"); Cursor changed = getContentResolver().query(updated.build(), null, null, null, null); Log.d(TAG, "number of members " + changed.getCount()); //create a JSON object out of the editable properties for (changed.moveToFirst(); changed.isAfterLast() == false; changed.moveToNext()) { JSONObject json = new JSONObject(); for (String att : changed.getColumnNames()) { if (ListMetaData.validAtts.contains(att)) { try { json.put(att, changed.getString(changed.getColumnIndex(att))); } catch (JSONException e) { // TODO Auto-generated catch block Log.d(TAG, "JSON exception in DatagramService"); e.printStackTrace(); } } } //include the GUID and job name //for identification try { json.put(JobMetaData.MemberTableMetaData.GUID, changed.getString(changed.getColumnIndex(JobMetaData.MemberTableMetaData.GUID))); json.put(JobMetaData.JobTableMetaData.JOB, jobName); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } packets.add(json); } changed.close(); } Log.d(TAG, "entering send loop"); try { out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); out.flush(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } for (JSONObject packet : packets) { Log.d(TAG, "supposedly sending"); try { //now write the data Log.d(TAG, "packet string: " + packet.toString()); out.write(packet.toString()); out.flush(); } catch (IOException e) { } } try { out.write("Done"); out.flush(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } stopSelf(); } And the test server that I am using (written in python): #!/usr/bin/env python import SocketServer import json class MemberUpdateHandler(SocketServer.BaseRequestHandler): def setup(self): print self.client_address, "connected" def handle(self): while True: self.JSONString = self.request.recv(8192).strip() if self.JSONString == "Done": return self.handleJSON() self.update() def handleJSON(self): JSONMember = json.loads(self.JSONString) print "GUID:", JSONMember['ManufacturingGUID'] print "Weight:", JSONMember['Weight'] def update(self): print "do something here" if __name__ == "__main__": ADDRESS = '' PORT = 4242 HOST = (ADDRESS, PORT) s = SocketServer.ThreadingTCPServer(HOST, MemberUpdateHandler) s.serve_forever() Here is the string that is being sent (it is long): {"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_5":"","RevisionCheckedBy_2":"","RevisionCheckedBy_1":"","EngineerVerifiedLeftComments":"","RequestVerifyLeftConnMaterial":"False","RequestEngineerVerify":"False","RevisionCheckedDate_3":"**NOT SET**","RevisionCheckedDate_2":"**NOT SET**","RevisionCheckedDate_1":"**NOT SET**","EngineerVerifiedLength":"False","BackCheckedDate":"**NOT SET**","SubmittedForApproval":"**NOT SET**","EngineerVerifiedSpecial":"False","CostCodeDescription":"","IFCStartDate_5":"**NOT SET**","TieForcesLeft":"False","Fireproofed":"False","ErectorAvailable":"False","RequestVerifyRightConnMaterial":"False","DetailCheckedDate":"**NOT SET**","ErectorNonSteelSupported":"False","BeamPent":"False","StockStatus":"","Sequence":"1","RequestVerifyLeftLoad":"False","DetailFinalCheckDate":"**NOT SET**","ErectorMemberPlaced":"**NOT SET**","InstanceStatus":"","EngineerVerifiedRightConn":"False","DateReceived":"**NOT SET**","MemberType":"Beam","ModelCheckDate":"**NOT SET**","ReasonForHold":"","EngineerVerifiedRightComments":"","ReceivedOnJobSite":"**NOT SET**","RequestVerifyRightLoad":"False","CostCodePrice":"0.0","NestStatus":"","DateDue":"**NOT SET**","ShopSequence":"","EngineerVerifiedSectionSize":"False","ActualLength":"144","InputDate":"**NOT SET**","ErectorCity":"Unknown","EngineerVerifiedSpecial_comments":"","Route4Description":"","EngineerVerifiedGrade":"False","RightLocation":"0.0xx144.0xx156.0xx","IFCFinishTime_2":"","IFCFinishTime_1":"","IFCFinishTime_4":"","Route3Description":"","IFCFinishTime_3":"","LoadStatus":"","ErectorLongitude":"","DateModelCompleted":"61299957600000","Grade":"##SEKRIT KODE!!##","IFCFinishTime_5":"","Route2Description":"","RequestVerifyCamber":"False","ProjectedFabricationComplete":"**NOT SET**","DetailedBy":"","DetailFinalCheckBy":"","Description":"W8x35","ProjectedShippedDate":"**NOT SET**","NestName":"","IFCStartDate_2":"**NOT SET**","IFCStartTime_1":"","IFCStartDate_1":"**NOT SET**","IFCStartDate_4":"**NOT SET**","IFCStartDate_3":"**NOT SET**","IFCStartTime_5":"","IFCStartTime_4":"","IFCStartTime_3":"","DateHeld":"**NOT SET**","IFCStartTime_2":"","LeftLocation":"0.0xx0.0xx156.0xx","Job":"Mobile_x_x_x_x_Demo_x_x_x_x_IN_x_x_x_x_2011","SpecialCutWeld":"False","RejectedBy":"","ErectionWelded":"**NOT SET**","RequestVerifyRightConnConfig":"False","Vendor":"","PackageNumber":"","RejectedByErector":"**NOT SET**","ModelCheckedBy":"","ApprovalStatus":"Not reviewed","RequestVerifyLeftConnConfig":"False","ErectorLatitude":"","LotName":"","ActualShipDate":"**NOT SET**","NestId":""} This is the error I get from the python server: ValueError: Unterminated string starting at: line 1 column 1435 (char 1435) which means that the string has been truncated to: {"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_ Any help would be greatly appreciated. Thanks in advance. UPDATE: I have updated the code to reflect my tinkering. The string received by the server is now {"DetailCheckedBy":"","SketchRight":"","DetailLength":"142.75","DetailedDate":"**NOT SET**","EngineerVerifiedBothConns":"False","HoldStatus":"Not held","RevisionLevel":"No Revision","MemberNumber":"28","RequestVerifySectionSize":"False","TieForcesRight":"False","InputBy":"","IFCFinishDate_4":"**NOT SET**","IFCFinishDate_5":"**NOT SET**","Weight":"438.408","IFCTaskUID_1":"","IFCFinishDate_1":"**NOT SET**","ErectorOrder":"","IFCFinishDate_2":"**NOT SET**","IFCFinishDate_3":"**NOT SET**","IFCTaskUID_4":"","IFCTaskUID_5":"","IFCTaskUID_2":"","SketchLeft":"","IFCTaskUID_3":"","ErectorSequences":"","ReasonRejected":"","MemberCategory":"","EngineerVerifiedLeftConn":"False","BarcodeId":"","ManufacturingGUID":"42bbf9cc-52da-4712-a5fc-e37c5a544c14","aess":"False","FabricationComplete":"**NOT SET**","UserComment2":"","UserComment3":"","LoadNumber":"","UserComment1":"","ErectionBolted":"**NOT SET**","RequestVerifyLength":"False","RequestVerifyGrade":"False","Painted":"False","HeatCertNumber":"","Route1Description":"","IsExisting":"No","ReceivedFromApproval":"**NOT SET**","BackCheckedBy":"","BatchNumber":"","CostCodeReference":"","PONumber":"","Piecemark":"B_25","ReleasedForFabrication":"**NOT SET**","MemberDescription":"BEAM","EngineerVerifiedMemberReady":"False","IFCTaskName_2":"","IFCTaskName_1":"","IFCTaskName_4":"","RequestVerifyMemberPosition":"False","IFCTaskName_3":"","Erected":"**NOT SET**","RevisionCheckedBy_3":"","IFCTaskName_5":"","RevisionCheckedBy_2":"","RevisionCheckedBy_1":"","EngineerVerifiedLeftComments":"","RequestVerifyLeftConnMaterial":"False","RequestEngineerVerify":"False","RevisionCheckedDate_3":"**NOT SET**","RevisionCheckedDate_2":"**NOT SET**","RevisionCheckedDate_1":"**NOT SET**","EngineerVerifiedLength":"False","BackCheckedDate":"**NOT SET**","SubmittedForApproval":"**NOT SET**","EngineerVerifiedSpecial":"False","CostCodeDescription":"","IFCStartDate_5":"**NOT SET**","TieForcesLeft":"False","Fireproofed":"False","ErectorAvailable":"False","RequestVerifyRightConnMaterial":"False","DetailCheckedDate":"**NOT SET**","ErectorNonSteelSupported":"False","BeamPent":"False","StockStatus":"","Sequence":"1","RequestVerifyLeftLoad":"False","DetailFinalCheckDate":"**NOT SET**","ErectorMemberPlaced":"**NOT SET**","InstanceStatus":"","EngineerVerifiedRightConn":"False","DateReceived":"**NOT SET**","MemberType":"Beam","ModelCheckDate":"**NOT SET**","ReasonForHold":"","EngineerVerifiedRightComments":"","ReceivedOnJobSite":"**NOT SET**","RequestVerifyRightLoad":"False","CostCodePrice":"0.0","NestStatus":"","DateDue":"**NOT SET**","ShopSequence":"","EngineerVerifiedSectionSize":"False","ActualLength":"144","InputDate":"**NOT SET**","ErectorCity":"Unknown","EngineerVerifiedSpecial_comments":"","Route4Description":"","EngineerVerifiedGrade":"False","RightLocation":"0.0xx144.0xx156.0xx","IFCFinishTime_2":"","IFCFinishTime_1":"","IFCFinishTime_4":"","Route3Description":"","IFCFinishTime_3":"","LoadStatus":"","ErectorLongitude":"","DateModelCompleted":"61299957600000","Grade":"##SEKRIT KODE!!##","IFCFinishTime_5":"","Route2Description":"","RequestVerifyCamber":"False","ProjectedFabricationComplete":"**NOT SET**","DetailedBy":"","DetailFinalCheckBy":"","Description":"W8x35","ProjectedShippedDate":"**NOT SET**","NestName":"","IFCStartDate_2":"**NOT SET**","IFCStartTime_1":"","IFCStartDate_1":"**NOT SET**","IFCStartDate_4":"**NOT SET**","IFCStartDate_3":"**NOT SET**","IFCStartTime_5":"","IFCStartTime_4":"","IFCStartTime_3":"","DateHeld":"**NOT SET**","IFCStartTime_2":"","LeftLocation":"0.0xx0.0xx156.0xx","Job":"Mobile_x_x_x_x_Demo_x_x_x_x_IN_x_x_x_x_2011","SpecialCutWeld":"False","RejectedBy":"","ErectionWelded":"**NOT SET**","RequestVerifyRightConnConfig":"False","Vendor":"","PackageNumber":"","RejectedByErector":"**NOT SET**","ModelCheckedBy":"","ApprovalStatus":"Not reviewed","RequestVerifyLeftConnConfig":"False","ErectorLatitude":"","LotName":"","ActualShipDate":"**NOT SET**","NestId":""}Done followed by a mess of whitespace. Enough that gedit has trouble loading it all. One step forward two steps back. :/
sizeof(int) may not be the same on both devices. So you probably should hardcode something if you want to pass a binary integer. If you evaluate int('\001\002\003\004\005\006\007\010'), you're unlikely to get what you want, and I believe that's close to what you're doing in your Python code. For one thing, the endianness of the two devices might be different, and for another, int() wants to evaluate ASCII or some other encoding, not raw endian-dependent integers. On the python side, you might find this useful: http://stromberg.dnsalias.org/~strombrg/bufsock.html I'm not sure about the out.write() you're using, but at the lower level of send(), there's no guarantee that your entire buffer will be written in a single send() - it's allowed to stop early and just return how much was sent. Hopefully, java protects you from that detail the way bufsock does for python.
Why are you "assuming" that the string has been truncated? print it and see what it actually is. Also, the string that is being sent (as you posted it) is not enclosed in {}, which means it is not proper JSON... I tried to copy/paste it in the interpreter, this raises a ValueError: ValueError: Extra data: line 1 column 17 - line 1 column 3952 (char 17 - 3952) I enclosed it in {} and it worked. You should try to see what the string you are receiving actually is on the python side, and then you can really see what's happening. I assume also, that since you are seeing the "Done" sent, then the content should have been sent completely.