commumicating between windows app and android app - android
I'm sorry if this is a very general question but I don't know where to start so I'm looking for ideas.
I have a windows app (music score editing) and I'm currently porting it to Andriod which is coming along well.
I would like to add the feature than documents created in the windows app can be sent to the users android tablet. I was wondering, how would I write some kind of listener on Android that the windows side could open a socket or something to and send data across to it, assuming both are on the same local network.
thanks
I think sending files directly over a local network isn't the best approach. You are prone to many user complaints that the sharing isn't working.. and this will mostly be due to their own network configuration issues.
Why not use a service like DropBox to implement file sharing?
Services like DropBox offer simple API that can be used in apps in order to save files into a remote folder, and read files from a remote folder.
This way, users will not have to be in the same network at all.. and most of the heavy-lifting of implementing file sharing will be done by a service that is focused around that.
Addition:
If you don't want to require an account for a separate service like DropBox, consider this approach: Implement a very simple DropBox-like service on your own web server. Make a simple script that will allow users to upload a file to your server anonymously via HTTP. After upload, they will receive a 5 digit id for this file, or some other link they could share. When using this id or link from the 2nd app, the file could be downloaded (again via HTTP). If you delete files automatically from the server after a few hours, you will not run out of space.
You can implement such a service with about 20 lines of PHP code. And the required apps code is extremely simple (since it only relies on HTTP). If you're worried about the costs of a web server, you can get one from about $5/month or even use a free service like Google App Engine (free if your bandwidth+space requirements are low).
Code example for the file upload. Downloading should be simple enough to do alone. Regarding the periodical file delete - the obvious approach is cron but I think it's easy to manage without it. Whenever you accept a new upload (in the PHP script), go over all the downloads and delete old ones.
i wrote a small thing so my windows app can find an instance of my android app running on the local network, here it is. this is the android code first
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import android.os.AsyncTask;
import android.util.Log;
public class TabSyncServer extends AsyncTask<Void, Void, Void> {
ServerSocket mServerSocket = null;
Socket mSocket = null;
DataInputStream mDataInputStream = null;
DataOutputStream mDataOutputStream = null;
#Override
protected void onPreExecute() {
try {
mServerSocket = new ServerSocket(2112);
//System.out.println("Listening :2112");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected Void doInBackground(Void... args) {
byte[] bytebuf = new byte[1024];
while (true) {
try {
mSocket = mServerSocket.accept();
mDataInputStream = new DataInputStream(mSocket.getInputStream());
mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
Log.d("TabSyncServer", "ip: " + mSocket.getInetAddress());
mDataInputStream.read(bytebuf);
String str = new String(bytebuf, "UTF8");
Log.d("TabSyncServer", "message: " + str);
if(str.contains("Hello Android")) {
Log.d("TabSyncServer", "sending reply");
mDataOutputStream.writeBytes("Hello Windows");
}
//
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (mSocket != null) {
try {
mSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (mDataInputStream != null) {
try {
mDataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (mDataOutputStream != null) {
try {
mDataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
and the windows MFC code
void CMainFrame::OnBrowseMobile() {
CMobileSync* con = new CMobileSync();
CString ipaddr_base;
int my_last_digit;
if(!con->getMyIP(ipaddr_base, my_last_digit)) {
setMobilePath("Can't find local network");
return;
}
for(int i=1 ; i<98 ; i++) {
if(i==my_last_digit)
continue; // don;t check self
CString ipaddr; ipaddr.Format("%s.%d", ipaddr_base, i);
bool res = con->ConnectToHost(ipaddr);
if(res) {
res = con->SendMsg ("Hello Android");
if(res) {
TRACE1("send ok %s\n",ipaddr.GetBuffer());
#define RD_BUF_LEN 80
char buffer[RD_BUF_LEN];
if(con->ListenOnPortBlocking(buffer, RD_BUF_LEN)) {
if(strncmp(buffer, "Hello Windows", 12)==0) {
TRACE1("reply ok %s", buffer);
setMobilePath(ipaddr);
con->CloseConnection ();
return;
}
}
} else {
TRACE("send FAILED\n");
}
}
con->CloseConnection ();
}
setMobilePath("No TabTrax on local network");
}
#include "stdafx.h"
#include <winsock.h>
#include "MobileSync.h"
#define TTPORT 2112
bool CMobileSync::getMyIP(CString& ipaddr_front, int& ipaddr_lastdigit)
{
char szBuffer[1024];
#ifdef WIN32
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 0);
if(::WSAStartup(wVersionRequested, &wsaData) != 0)
return false;
#endif
if(gethostname(szBuffer, sizeof(szBuffer)) == SOCKET_ERROR)
{
#ifdef WIN32
WSACleanup();
#endif
return false;
}
struct hostent *host = gethostbyname(szBuffer);
if(host == NULL)
{
#ifdef WIN32
WSACleanup();
#endif
return false;
}
//Obtain the computer's IP
unsigned char b1, b2, b3, b4;
b1 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b1;
b2 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b2;
b3 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b3;
b4 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b4;
ipaddr_front.Format("%d.%d.%d", b1, b2, b3);
ipaddr_lastdigit = b4;
#ifdef WIN32
WSACleanup();
#endif
return true;
}
//CONNECTTOHOST – Connects to a remote host
bool CMobileSync::ConnectToHost(const char* IPAddress)
{
//Start up Winsock…
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
//Did something happen?
if (error)
return false;
//Did we get the right Winsock version?
if (wsadata.wVersion != 0x0202)
{
WSACleanup(); //Clean up Winsock
return false;
}
//Fill out the information needed to initialize a socket…
SOCKADDR_IN target; //Socket address information
target.sin_family = AF_INET; // address family Internet
target.sin_port = htons (TTPORT); //Port to connect on
target.sin_addr.s_addr = inet_addr (IPAddress); //Target IP
mSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
if (mSocket == INVALID_SOCKET)
{
return false; //Couldn't create the socket
}
//Try connecting...
if (connect(mSocket, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
{
return false; //Couldn't connect
}
return true; //Success
}
//CLOSECONNECTION – shuts down the socket and closes any connection on it
void CMobileSync::CloseConnection ()
{
//Close the socket if it exists
if (mSocket)
closesocket(mSocket);
mSocket=0;
WSACleanup(); //Clean up Winsock
}
int CMobileSync::SendMsg (char* szpText, int buflen)
{
if(buflen==0)
buflen = strlen(szpText);
int ret = send(mSocket, szpText, buflen, 0);
TRACE1("CMobileSync::SendMsg sent %d bytes\n", ret);
return ret;
}
WSADATA w;
//LISTENONPORT – Listens on a specified port for incoming connections
//or data
bool CMobileSync::ListenOnPortBlocking(char* buffer, int buflen)
{
//Now we can start listening (allowing as many connections as possible to
//be made at the same time using SOMAXCONN). You could specify any
//integer value equal to or lesser than SOMAXCONN instead for custom
//purposes). The function will not //return until a connection request is
//made
// listen(s, SOMAXCONN);
memset(buffer, 0, sizeof(buffer)); //Clear the buffer
int iTimeout = 1600;
setsockopt( mSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&iTimeout, sizeof(iTimeout));
//Put the incoming text into our buffer
int ret = recv (mSocket, buffer, buflen-1, 0);
//Don't forget to clean up with CloseConnection()!
if(ret != SOCKET_ERROR)
return true;
int err = WSAGetLastError();
return false;
}
its not tested extensively but it is running
this maybe useful to someone
Related
Android app not synchronized with Arduino Serial communication
I have a simple sonar arduino project so that it prints the distance every second. I have implemented an android app using UsbSerial to communicate with my arduino. So far so good, I am able to receive data and the data I receive is correct, but the problem is that the values are sometimes not properly sent. Here is the sample output I receive: data: 7 data: 1 data: data: 71 and here is the code that generates output: private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { #Override public void onReceivedData(byte[] arg0) { try { String data = new String(arg0, "UTF-8"); System.out.println("data: " + data); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }; So in my opinion there is 2 problems here: Lines 1 & 2 must be just one line with the value of 71 Line 3 should not exists as my application is listening onReceivedData and arduino always send something. Any help would be much appreciated.
I have found a solution for the issue. by reading this link I noticed that I need to do some manipulation on the data I receive in the onReceivedData method. So I changed the mCallBack as follow: private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { #Override public void onReceivedData(byte[] arg0) { if(arg0!= null && arg0.length > 0){ if (isStartByte(arg0[0])) { printData(); clearBytes(); } appendBytes(arg0); } } }; and here is the other methods I added: private void clearBytes(){ buffer=new byte[8]; bufferSize = 0; } private void appendBytes(byte[] buf){ System.arraycopy(buf, 0, buffer, bufferSize, buf.length); bufferSize += buf.length; } private void printData() { if (bufferSize == 0) { return; } byte[] buf = new byte[bufferSize]; System.arraycopy(buffer, 0, buf, 0, bufferSize); String data = null; try { data = new String(buf, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (null != data && !data.isEmpty()) { System.out.println("data: " + data); } } public boolean isStartByte(byte firstChar){ return firstChar=='A'; } And also I modified the Arduino code and added character A to the beginning of the serial output. This solves the issue, however I think this is not the best practice. I think the UsbSerial library should provide better output handling( or maybe I am wrong and this is the nature of working with serial communication ).
Send continuous bluetooth stream from Android to Arduino
I'm working on a simple vehicle project, made with Arduino Uno and controlled by an Android App. My matter is to send continuous stream from the app to my bluetooth module (HC-06) on Arduino. I did it with onTouch events and a new thread called from my main activity, but something is obviously wrong because the app seems to send each command as i want it to do, but the Arduino waits until the finger is off the button and receives all data (from action.down to action.up) at a time. To understand : I update a small string like this "1255090" each time a command button is action.down or action_move, convert it to bytes and send it via bluetooth. If i briefly click on the button, Arduino will receive the correct string "1255090", but if i maintain my finger on the button, Arduino waits for the string, and when i release the button, Arduino receives for example "125509012540901253090125209012510901252090" (depending on how long i clicked). Android activity (partial) drive.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent m) { if (m.getAction() != MotionEvent.ACTION_UP) { accelerer(); // inscreases the speed str_flux(); // constructs the string byte[] bytes = new byte[0]; try { bytes = flux.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } sendReceiveBT.write(bytes); // calls the thread's method } else{ralentir();} return true; } }); Thread package com.*.vehicle.util; import android.bluetooth.BluetoothSocket; import android.util.Log; import java.io.IOException; import java.io.OutputStream; public class SendReceiveBytes implements Runnable { private BluetoothSocket btSocket; private OutputStream btOutputStream = null; String TAG = "SendReceiveBytes"; public SendReceiveBytes(BluetoothSocket socket) { btSocket = socket; try { btOutputStream = btSocket.getOutputStream(); } catch (IOException streamError) { Log.e(TAG, "Error when getting input or output Stream"); } } public void run() { byte[] buffer = new byte[1024]; int bytes; } public void write(byte[] bytes) { try { btOutputStream.write(bytes); // Send the bytes to Arduino btOutputStream.flush(); // don't know if it really does something... Log.e(TAG, "SUCCESS !"); } catch (IOException e) { Log.e(TAG, "Error when writing to btOutputStream"); } } } Arduino loop void loop() { s = Serial.readString(); // 1255090 if (s!=""){ Serial.println(s); bt_direction = s.substring(0,1).toInt(); bt_speed = s.substring(1,4).toInt(); bt_angle = s.substring(4,7).toInt(); s = ""; } else{ if (bt_speed>0){ for(int i=bt_speed;i>=0;i--){bt_speed--;} } else{ bt_speed = 0; } } if (bt_direction==1){bt_dir = true;} else{bt_dir = false;} if (bt_speed==0){stop_motor();} else{dc_motor(bt_speed, bt_dir);} Serial.println(bt_direction); servo_turn(bt_angle); }
If I am getting you correctly, you can easily handle it using multiple states. For example, State1: 123456: is for tap, State2: 123457: is for press & hold, State3: 123458: is for release, And so on. And in you ui detect whether user is tapping or press and hold. If press and hold , instruct arduino to do something until receives release. In this way you can even handle the situation without continuously sending bit, And as per my understanding you don't need this. Correct me if I am wrong. Thanks !!!
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.
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.
Network timed out exception
I have an Android application which connects to an Arduino server and sends it sockets on a button press, but as soon as I press the button it waits a little while and then throws "Connection timed out". I know the Arduino works; I tried it over the browser and it was fine. Why can't my application access it? The Android code: Button.OnClickListener buttonConnectOnClickListener = new Button.OnClickListener() { public void onClick(View v) { Log.i(Tag,"connecting to Server"); try { Log.i(Tag,"Enters try"); socket = new Socket("161.53.168.112", 8888); Log.i(Tag,"stvorio socket"); dataOutputStream = new DataOutputStream(socket.getOutputStream());//and stream Log.i(Tag,"Writing 1 on socket."); dataOutputStream.writeBytes("1"); } catch (UnknownHostException e) { Log.i(Tag,e.toString()); } catch (IOException e) { Log.i(Tag,e.toString()); } catch (Exception e) { Log.e(Tag, e.toString()); And here is the code used in the Arduino. It's quite simple, so I can't understand what went wrong. I used many logs, because I wanted to see where the mistake is. I use my Arduino as a server and post something on it. If I type in 161.53.168.112:8888 in a web browser, it finds it and can send a request but my Android phone gets nothing, even using the browser, and not an app. I can't access my server. AM I maybe missing some permission in the server or on the Android? byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x36, 0xFF }; byte ip[] = { 161, 53, 168, 114 }; int serverPort = 8888; #define kitchenLight = 9; Server server(serverPort); void setup() { Serial.begin(9600); Ethernet.begin(mac, ip, gateway, subnet); pinMode(kitchenLight,OUTPUT); server.begin(); } void loop() { Client client = server.available(); if(client) { while(client.connected()) { if(client.available()) { char c = client.read(); appMessage += c; if (c == '\n') { Serial.println("Message from Client: "+appMessage); if(appMessage.IndexOf("kitchenLight1") != -1) { digitalWrite(kitchenLight,HIGH); } } } } } client.close(); }
After you make a connection between your Arduino and Android, you should add a delay, like, for a second or two (more likely two), because it takes that time for Arduino to get ready receiving commands. Hope this helps :)