Cannot send byte Data from Android App to Python Server using sockets - java

I have tried everything to get this to work. Basically I have an Android App which receives data from a Python based Server on a local network connection. I can receive Data no problem. However when I attempt to send data back the App crashes and the Python server receives blank data. I have tried several different approaches but non have worked. Here is the Python method I have written to receive the message:
def checkReply(self):
reply = "no reply yet"
self.conn.settimeout(1)
try:
test = self.conn.recv(1024)
except:
self.conn.timeout;
print("I failed to hear this") #Debug to help see if I have heard an incomming message
try:
data = test.decode()
reply = data
except:
print("I failed to decode this") #Debug to help see if I could not decode an incomming message
print(reply)
self.conn.settimeout(0)
My client on my Android application looks like this:
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "No data has been sent yet";
TextView textResponse;
Socket socket = null;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse = textResponse;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice: inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response = byteArrayOutputStream.toString("Ascii");
}
byteArrayOutputStream.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
protected String getSite(){
return response;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void returnMsg(){
try (DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream())) {
byte[] buf = "hello".getBytes("UTF-8");
outToClient.writeBytes("Test");
outToClient.flush();
} catch (IOException e) {}
}
}
I am having to test on a physical device so I have no log to trace the error message. Any help would be greatly appreciated. Thanks

I managed to solve the issue. I needed to flush the buffer before trying to send any data back via the socket

Related

Transfer file from android to server via socket

There is such a problem. To transfer files in an Android application, we use a Socket, we encrypt and transfer to the server, there the data is decrypted and transmitted by the usual POST method, but when some data is transferred, the file is not loaded, but returns 500 The error stream terminated unexpectedly. One xlsx file is transferred. but the other is gone. We also saw that if the file is still uploaded to the server and we download it, the file is broken and at the end a piece of header Content-Disposition: form-data; name = "publicAccess" false.
ANDROID CODE
#Override
public void run() {
try {
byte[] request = new byte[4096];
byte[] reply = new byte[8192];
final InputStream inFromClient = sClient.getInputStream();
final OutputStream outToClient = sClient.getOutputStream();
SSLSocket remoteSocket = tlsConnectionService.createSSLSocket(remoteHost, remotePort);
final InputStream inFromServer = remoteSocket.getInputStream();
final OutputStream outToServer = remoteSocket.getOutputStream();
// a new thread for uploading to the server
new Thread() {
public void run() {
int bytes_read;
try {
while ((bytes_read = inFromClient.read(request)) != -1 ) {
String newReq = new String(request);
if (newReq != null) {
outToServer.write(newReq.replace(LOCAL_SOCKET_URL, remoteHost).getBytes(), 0, bytes_read);
outToServer.flush();
}
}
} catch (IOException e) {
if (!(e instanceof SocketException)) {
Log.e(M.CPP, e.toString());
}
}
}
}.start();
// current thread manages streams from server to client (DOWNLOAD)
int bytes_read;
try {
while ((bytes_read = inFromServer.read(reply)) != -1 ) {
outToClient.write(reply, 0, bytes_read);
outToClient.flush();
}
} catch (IOException e) {
Log.e(M.CPP, e.toString());
} finally {
try {
remoteSocket.close();
} catch (IOException e) {
Log.e(M.CPP, e.toString());
}
}
sClient.close();
} catch (IOException e) {
Log.e(M.CPP, e.toString());
}
}
Server CODE
#PostMapping(
value = {"/file", "/file/" },
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public ResponseEntity<FileEntryDto> upload(
#PathVariable("source") String source,
#AuthenticationPrincipal JwtUserDetails currentUser,
#Validated FileUploadRequest request
) {
return ResponseEntity.ok(
converters.fileToDto(
fileOperationService.upload(Source.fromName(source), request, currentUser.getUserId()))
);
}
The request that we see when inspecting app
request

Why Can't I communicate with my server?

I have been trying to make a client project on Android Studio that will connect to a server that I made in Python (Pycharm). As for the IP used, I entered at the server the local host and in the client the IPV4 of the computer's server.
The debugging was made through the phone itself and not the emulator.
When I tried running the code and connect to the server through out the ipv4 with the same port, I got connection timed out.
At the moment, the debugger is stuck on the client class while trying to get a message from the server, the - "while ((bytesRead = inputStream.read(buffer))" - line while on the server, the code did not recieve any message from the client and thus its stuck on receiving.
How do I solve this issue?
Client code: - Where the connection occurs
public class RequestAndAnswer extends AsyncTask<Void, Void, Void> {
private String dstAddress,result1;
private int dstPort;
private String response = "";
private String out;
RequestAndAnswer(String output)
{
dstAddress = "1.5.0.66"; //fake ipv4
out= output;
dstPort= 8886;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
//send out to server
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF(out);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
The main code:
public void onClick(View v)
{
if(v == loginButton)
{
String userNameString = userName.getText().toString();
String passwordString = password.getText().toString();
String output ="100"+
intToString(userNameString.length())
+userNameString
+ intToString(passwordString.length())
+passwordString;
RequestAndAnswer myClient = new RequestAndAnswer(output);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
myClient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
myClient.execute();
String answer="";
do {
answer = myClient.getResult(); /**In order to make sure that I
will get my response after the
communication started between
the server and the client **/
}
while(answer.matches(""));
if(answer.matches("1100"))
{
Intent i = new Intent(this,Computer_choosing_selection_activity.class);
i.putExtra("username",userNameString);
startActivity(i);
finish();
}
else if(answer.matches("1101"))
{
String error = "The username and password do not match";
errorText.setTextColor(Color.RED);
errorText.setText(error);
}
else
{
String error = "Could not connect";
errorText.setTextColor(Color.RED);
errorText.setText(error);
}
}
The AndroidManifest.XML includes the following lines -
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
The server code: - In python
import socket
import sys
HOST = '127.0.0.1' # Symbolic name, meaning all available interfaces
PORT = 8886 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = s.recv(1024)
number = data.substr(0,3)
if(number == "100"):
data = data[4:]
len=data[0:3]
data=data[2:]
name = data[:int(len)]
data = data[int(len):]
len=data[0:3]
data=data[2:]
password = data[:int(len)]
if((name == "Tod") and (password == "Aa123456")):
conn.send("1100")
else:
conn.send("1101")
s.close()
EDIT:
I changed in the server the address to the IPV4 instead of the local 127.0.0.1 and I managed to connect although it gave me the following error before hand
"Socket.error: [Errno 10057] request to send or receive data was denied because the component is not connected to the socket and provided an address (when sending data socket unit via a call to sendto)"
after this message I got an output of"connected" and the program shut down.

Java Android Send a data to server application never use a onPostExecute()

I have a problem with send a data to server, to connect with server I used a socket. To send a data to server I use a AsyncTask. And I have a problem with :
when a application send a data , my app don't see a finish this action, it never use onPostExecute().
This is my code :
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port) {
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
// if (pingHost(1000)) {
socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
byte[] theByteArray = message.getBytes();
lengthMessage = (short) theByteArray.length;
outputStream.writeByte((byte) 0xB);
outputStream.writeByte((byte) 0xA);
outputStream.writeByte((byte) 0xA);
outputStream.writeByte((byte) 0xD);
outputStream.writeShort(lengthMessage);
outputStream.write(theByteArray);
outputStream.writeShort(width);
outputStream.writeShort(height);
outputStream.writeInt(lengthbmp);
outputStream.writeInt(lengthResizebmp);
outputStream.writeShort(11);
outputStream.write(imageInByte );
outputStream.write(imageResizeInByte);
outputStream.writeByte((byte) 0xB);
outputStream.writeByte((byte) 0xE);
outputStream.writeByte((byte) 0xE);
outputStream.writeByte((byte) 0xF);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
outputStream.flush();
outputStream.close();
} catch (UnknownHostException e) {
e.printStackTrace();
isSuccsess = false;
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
e.printStackTrace();
Log.d("la", "nie udało sie");
isSuccsess = false;
response = "IOException: " + e.toString();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (socket != null) {
try {
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(isSuccsess){
Toast.makeText(MainActivity.this, "Zdjęcie zostało wysłane !" , Toast.LENGTH_LONG).show();
bm = null;
clearEt();
ivImage.setImageBitmap(bm);
}
else{
Toast.makeText(MainActivity.this , "Nie udało się wysłać zdjęcia !" , Toast.LENGTH_LONG).show();
}
pbWheel.setVisibility(View.INVISIBLE);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pbWheel.setVisibility(View.VISIBLE);
}
}
You can use AsyncTask<Void,Void,Integer>, and return any integer instead of a null in the doInBackground.
Just replace (in the doInBackground)
return null;
with
return 1;
and replace (in the AsyncTask declaration)
public class MyClientTask extends AsyncTask<Void, Void, Void> {
with
public class MyClientTask extends AsyncTask<Void, Void, Integer> {
Note that getInputStream() is a blocking call. It will block, until it receives data from server. In your case, you are not flushing data to server before calling getInputStream(), which will wait for response from server. Now you haven't sent any data to server (which I guess you should in your case to get response), socket will block the thread waiting for input.
You should flush data before getting input stream and making your thread sleep. Also close all streams once you are done, as closing stream will close underlying socket. From the docs:
Closing the returned OutputStream will close the associated socket.
Closing the returned InputStream will close the associated socket.
outputStream.flush(); // flush it before sleep and don't close
// outputStream.close(); don't close it here
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
Is you execution going after this lines?
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
Use URLConnection instead of socket inside AsyncTask.

Calling a java client in an android application

I have a client which can send some information to a server via TCP :
public class IR {
private String host; //server IP address indicated here, I deleted it for posting here
private int port = 6789;
private String sentence;
private String reply;
public IR(String type) {
try {
Socket clientSocket = new Socket(host,port); //IP du server ("localhost" pour un server local) et port utilisé
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Gson gson = new GsonBuilder().create();
FileReader file = new FileReader("data/userInfo.json");
String json = "";
int i = 0;
while ((i = file.read()) != -1)
json += (char)i;
User user = gson.fromJson(json, User.class);
String user_id = user.getID();
int bus_id = user.getBusID();
sentence = "alerte " + type + " " + user_id + " " + bus_id;
System.out.println("SENTENCE: " + sentence);
outToServer.writeBytes(sentence + '\n');
reply = inFromServer.readLine();
System.out.println("ANSWER: " + reply);
clientSocket.close();
}
catch (Exception io) {
System.out.println("Connection refusée: arrêt");
}
}
}
I am calling this in my android application : I have a button which use this method when I'm clicking on it :
public void signalerComplet(View view)
{
client = new IR("complet");
Toast.makeText(this, "envoyé", Toast.LENGTH_SHORT).show();
}
But my server doesn't get anything .
Though, I ma sure that my client works when I'm using it not in my android application .
Could somebody say to me what I am missing here ?
EDIT after getting Hector's help : the server gets my "bloubloubloub" but I get an android.os.NetworkOnMainThreadException on the "int size = in.read(data);" ...
private Socket socket;
public void signalerComplet(View view)
{
PrintWriter out = null;
InputStream in=null;
byte[] data = new byte[5120];
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
}
catch (IOException e) {
e.printStackTrace();
}
out.println("bloubloubloub" + '\n');
out.flush();
try {
in = socket.getInputStream();
int size = in.read(data);
}
catch (IOException e) {
e.printStackTrace();
}
Log.e("data from server", data.toString());
}
type.equals(null) will always be false as if the variable type actually holds a null value it will throw a NullPointerException as there is no method equals for the null value. Therefore the if body will never execute.
The correct way to match if a variable is null is by the == operator.
if (type == null) {
// do this
} else {
// do that
}
equals() on a String should be used to compare against another String.
In Android you can't just put all this code in the onCreate method (for example) and run it, because you can't start a proccess that blocks the main thread, in this case Socket clientSocket = new Socket(host,port); will block the main thread and you app will crashes. You need do this tcp communication using threads. Please try this code and follow this algorithm:
Create this inner class, this will excecute the socket connection using threads:
class ClientThread implements Runnable {
#Override
public void run() {
try {
socket = new Socket(ipServer, portServer);
} catch (UnknownHostException e1) {
threadMsg("Connection fails");
} catch (IOException e1) {
threadMsg("Connection fails");
}
}
}
In onCreate Method call this
new Thread(new ClientThread()).start();
And in you send button should put something like this:
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
} catch (IOException e) {
e.printStackTrace();
}
out.println(messageToServer);
out.flush();
And this should send the string to server socket. Also you need add some basic validations.
EDIT: To get data from server, add this code in a new onClick button method:
byte[] data = new byte[5120];
try {
in = socket.getInputStream();
int size = in.read(data);
// see the received data from server in you LogCat
Log.e("data from server", data.toString());
} catch (Exception e) {
e.printStackTrace();
}
Hope it helps.
When you do:
client = new IR("complet");
You will fall at the else statement in your IR constructor which does nothing despite to close connection.
Here is what I've done . Thanks again to Hector for his help . It works great . Anything which could be "magnified" would be appreciated . :)
public class SignalerProblemeActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signaler_probleme);
}
public void signalerComplet(View view)
{
new Thread(new CompletThread()).start();
Toast.makeText(this, "Signalement de bus complet envoyé", Toast.LENGTH_SHORT).show();
}
class CompletThread implements Runnable {
#Override
public void run() {
Socket socket=null;
User u = new User("momo",12);
String sentence="alerte complet "+u.getID()+u.getBusID();
try {
//CREATION SOCKET
socket=new Socket("123.456.789.10",6789);
//SENDING
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(sentence);
//GETTING
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String mstr=br.readLine();
Log.e("CLIENT",mstr);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}catch(Exception e)
{
Log.e("CLIENT",e.toString());
}
}
}
}

Android:socket communication

I am trying to create simple app with android client and java server
android client is able to send message to server(java)
while when i try to read server reply
error:socket closed.
line(if((receiveMessage = receiveRead.readLine()) != null) )
public class ClientConnectorTask extends AsyncTask<String, Void, Integer> {
private Socket client;
private PrintWriter printwriter;
protected Integer doInBackground(String...strings) {
// validate input parameters
if (strings.length <= 0) {
return 0;
}
// connect to the server and send the message
try {
client = new Socket("192.168.1.4", 7777);
printwriter = new PrintWriter(client.getOutputStream(),true);
//while(true){
InputStream istream = client.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
String receiveMessage;
while (true){
// printwriter.write(strings[0]);
printwriter.print(strings[0]);
printwriter.flush();
printwriter.close();
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
}
//}
//client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
protected void onPostExecute(Long result) {
return;
}
}
Closing the PrintWriter inside the loop doesn't make sense, and closing it before the readLine() call doesn't make sense either. Closing either the input or the output stream of a Socket closes the other stream and the socket.

Categories