I am sending a String from an Android device to a python server via TCP socket, but when the message arrives on the server, there are extra characters in the front. For example, if I send the string
asdf
the result on the server would be
\x00\x13asdf
Anyone know why these characters are added to the front of the string? Is there a way to avoid this, or should I just cut these out at the server end?
For the reverse, the server sends
fdsa
The Android client receives
Nullfdsa
Client Code (Written in Android, Java):
public static class PlaceholderFragment extends Fragment {
TextView recieve;
EditText addressText, portText, messageText;
Button send, test;
Socket socket = null;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_customize_gateway, container, false);
recieve = (TextView) rootView.findViewById(R.id.textView1);
addressText = (EditText) rootView.findViewById(R.id.editText1);
portText = (EditText) rootView.findViewById(R.id.editText2);
messageText = (EditText) rootView.findViewById(R.id.editText3);
send = (Button) rootView.findViewById(R.id.send);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncTCPSend tcpSend= new AsyncTCPSend(addressText.getText().toString(),Integer.parseInt(portText.getText().toString()), messageText.getText().toString());
tcpSend.execute();
}
});
return rootView;
}
public class AsyncTCPSend extends AsyncTask<Void, Void, Void> {
String address;
int port;
String message;
String response;
AsyncTCPSend(String addr, int p, String mes) {
address = addr;
port = p;
message = mes;
}
#Override
protected Void doInBackground(Void... params) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 4999);
DataOutputStream writeOut = new DataOutputStream(socket.getOutputStream());
writeOut.writeUTF(message);
writeOut.flush();
ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream writeIn = socket.getInputStream();
while((bytesRead = writeIn.read(buffer)) != -1) {
writeBuffer.write(buffer,0,bytesRead);
response += writeBuffer.toString("UTF-8");
}
response = response.substring(4); //Server sends extra "Null" string in front of data. This cuts it out
} catch (UnknownHostException e){
e.printStackTrace();
response = "Unknown HostException: " + e.toString();
System.out.println(response);
} catch (IOException e) {
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
Server Code (In Python):
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
#Connect to database
try:
from pymongo import MongoClient
dbclient = MongoClient()
db = dbclient.WDI_database
print("Database Connected")
except pymongo.errors.ConnectionFailure as e:
print("Database Failed: {}".format(e))
col = db.users
data2 = str(self.request.recv(1024), 'utf-8')
print("Server: {}".format(data2));
data = data2.split("||")
try:
#[2:] because we get two extra symbols in front of the username from Android
username = data[0][2:]
except IndexError:
username = ""
try:
password = data[1]
except IndexError:
password = ""
try:
camunits = data[2]
except IndexError:
camunits = 0
try:
homunits = data[3]
except IndexError:
homunits = 0
post = {"user": username,
"pass": password,
"cam": camunits,
"disp": homunits}
col.insert(post)
print(col.count())
response = bytes("Received data for: {}".format(username), 'utf-8')
self.request.sendall(response)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
# Port 0 means to select an arbitrary unused port
HOST, PORT = "", 5000
tcpserver = ThreadedTCPServer((HOST, PORT-1), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=tcpserver.serve_forever)
server_thread.daemon = True
server_thread.start()
print("TCP serving at port", PORT-1)
while True:
pass
tcpserver.shutdown()
I think I got some explanations about the extra characters.
In the java code, you are not getting an extra "Null" from the socket, the response string variable is not initialized, by default it is null, and you say response += writeBuffer.toString("UTF-8"); so you append something to a null string, which happened to be "null" + something.
I would initialize the variable in the declaration or just before the while loop:
String response = "";
In the Phyton code, I see nothing wrong, therefore I'd suggest you to write what you send to the Log and see if the extra characters are in the bytes you send.
Instead of writeOut.writeUTF(message);
try socket.getOutputStream().write(message.getBytes()); // UTF-8 is the default.
and write it to the Log:
android.util.Log.w("SENT", String.format("[%s] %d", message, message.length()));See the log to find out what you're really sending.
Let java send the extra character. It did in my case too.
I used -
data2 = data.strip()
if data2 == "(your desired data)"
//execution instructions
and so on.
Related
I'm trying to call a website from my android watch but the thread exits (The thread 0x5 has exited with code 0 (0x0)) without a result.
I added the permissions "Internet" and "Network_state", which does not change the result. Below my code (done in Tizen and pure Xamarin):
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
textView = FindViewById<TextView>(Resource.Id.text);
Button mybtn = FindViewById<Button>(Resource.Id.btnCal);
SetAmbientEnabled();
try
{
mybtn.Click += delegate
{
Task<string> callTask = calculateRoute();
callTask.Wait();
string astr = callTask.Result;
};
}
catch (Exception ex)
{
string tt = ex.ToString();
}
}
private async Task<string> calculateRoute()
{
HttpClient client;
try
{
String RestUrl = "https://www.google.com";
var uri = new Uri(string.Format(RestUrl, string.Empty));
client = new System.Net.Http.HttpClient();
var response = await client.GetAsync(uri);
var content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
string tt = ex.ToString();
return "";
}
}
Do you have any idea?
Thanks, Jeppen
After quite some research I found the solution thanks to: https://github.com/Samsung/Tizen-CSharp-Samples/tree/master/Wearable
Give the app the following permissions:
<privilege>http://tizen.org/privilege/internet</privilege>
<privilege>http://tizen.org/privilege/network.get</privilege>
<privilege>http://tizen.org/privilege/download</privilege>
C# code
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.lu");
//get the data
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string tt = ((HttpWebResponse)response).StatusDescription + "\n";
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
Happy coding, Jeppen
I want to send and receive messages from my socket server which is created in python on windows with the help of twisted API. My client is going to be my android phone through I am going send my string messages. Here is my code. can someone please help out.
public class MainActivity extends AppCompatActivity
{
//TextView textView;
Button sendButton;
Button connect;
EditText message;
OutputStream outputStream;
InputStream inputStream;
Socket socket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendButton = (Button) findViewById(R.id.sendButton);
connect = (Button) findViewById(R.id.button);
message = (EditText) findViewById(R.id.message);
connect.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
connect.setText("Disconnect");
AsyncTask asyncTask = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects)
{
try {
socket = new Socket("192.168.100.106",8888);
try {
outputStream = socket.getOutputStream();
inputStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
connect.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
sendButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view)
{
PrintWriter out = new PrintWriter(outputStream);
String mes = message.getText().toString();
out.print(mes);
}
});
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
asyncTask.execute();
}
});
}
}
And here is my socket server script coded in python with the help of twisted API.
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
import ctypes # An included library with Python install.
class DataTransfer(Protocol):
def connectionMade(self):
#self.transport.write("""connected""")
self.factory.clients.append(self)
print "clients are ", self.factory.clients
self.username = ""
self.password = ""
self.auth = False
self.ipaddress = self.transport.getPeer()
print self.ipaddress
def connectionLost(self, reason):
self.factory.clients.remove(self)
print reason
def dataReceived(self, data):
print data
a = data.split(':')
if len(a) > 1:
command = a[0]
content = a[1]
msg = ""
self.message(msg)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = DataTransfer
factory.clients = []
reactor.listenTCP(8888, factory)
print "Server started"
reactor.run()
Presently I am able to communicate (ie. connect and disconnect with the server.) but its just that I am not able to send and receive messages.
Instead of PrintWriter out = new PrintWriter(outputStream); directly use the outputStream and it should work. :)
I wrote a simple UDP transfer between an Android App and Python Server. I know that the system is working because when I try to connect on a local ip address (192.168.X.X), the correct message is sent and recieved. However, this does not work when I try to use a public IP address. Does anyone know why and how I can try to fix this?
I am trying to implement UDP holepunching, having the server act as the target client of the Android one, but I cannot get the 2nd client's UDP packet to the Android one, it never gets picked up on the Android's side. Would having a 2nd machine act as the 2nd client fix this, or is my code incomplete?
Does my provider (T-Mobile) matter for UDP packet communication?
Client (Android):
public class CustomizeGatewayActivity extends ActionBarActivity {
AsyncUDPReceiver aReceive = null;
static TextView recieve = null;
public static class PlaceholderFragment extends Fragment {
EditText addressText, portText, messageText;
Button udpsend, tcpsend;
Socket socket = null;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_customize_gateway, container, false);
recieve = (TextView) rootView.findViewById(R.id.textView1);
addressText = (EditText) rootView.findViewById(R.id.editText1);
messageText = (EditText) rootView.findViewById(R.id.editText3);
udpsend = (Button) rootView.findViewById(R.id.UDP);
udpsend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncUDPSend aSend = new AsyncUDPSend(addressText.getText().toString(), messageText.getText().toString());
aSend.execute();
}
});
public class AsyncUDPSend extends AsyncTask<Void, Void, Void> {
String address = "";
String message = "";
String response = "";
AsyncUDPSend(String addr, String mes) {
address = addr;
message = mes;
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
DatagramSocket dsocket = null;
try {
dsocket = new DatagramSocket();
dsocket.setSoTimeout(10000);
InetAddress dest = InetAddress.getByName(address);
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), dest, 5001);
dsocket.send(packet);
System.out.println("Sent");
byte[] resp = new byte[1024];
DatagramPacket recv = new DatagramPacket(resp, resp.length);
System.out.println("Waitng for Response");
dsocket.receive(recv);
System.out.println("Received");
response = new String(recv.getData());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (dsocket != null) {
dsocket.close();
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
#Override
protected void onResume() {
super.onResume();
aReceive = new AsyncUDPReceiver();
aReceive.start();
}
#Override
protected void onPause() {
super.onPause();
aReceive.kill();
}
public class AsyncUDPReceiver extends Thread {
boolean keepRunning = true;
String response = "";
Runnable updateText = new Runnable(){
public void run() {
if(aReceive == null && recieve == null)
return;
recieve.setText(response);
}
};
public void run() {
android.os.Debug.waitForDebugger();
System.out.println("running");
DatagramSocket dsock = null;
byte[] message = new byte[1024];
DatagramPacket dpack = new DatagramPacket(message, message.length);
try {
dsock = new DatagramSocket(5002);
System.out.println(dsock.toString());
while(keepRunning) {
dsock.receive(dpack);
response = new String(dpack.getData());
System.out.println(response);
runOnUiThread(updateText);
}
} catch (SocketException e) {
// TODO Auto-generated catch block
response = "SocketException: " + e.toString();
System.out.println(response);
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
response = "IOException: " + e.toString();
System.out.println(response);
e.printStackTrace();
} finally {
if(dsock != null)
dsock.close();
}
}
public void kill() {
keepRunning = false;
}
}
}
Server (Python):
class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request[0].strip().decode("utf-8")
print("{} Recieved: ".format(self.client_address) + data)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
response = data.upper()
sock.sendto(bytes(response, "utf-8"), self.client_address)
print("{} Sent: {}".format(self.client_address,response))
class ThreadedUDPServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
pass
if __name__ == "__main__":
# Port 0 means to select an arbitrary unused port
HOST, PORT = "", 5000
udpserver = ThreadedUDPServer((HOST,PORT+1), ThreadedUDPRequestHandler)
udp_thread = threading.Thread(target=udpserver.serve_forever)
udp_thread.daemon = True
udp_thread.start()
print("UDP serving at port", PORT+1)
while True:
pass
udpserver.shutdown()
Are you supplying the expected value to InetAddress.getByName(address);
Also since you are trying to do something in background,it will be better if you run a service with wake lock so that you eliminate errors caused due to killing of process.
I am trying to write an app that sends a string to a specified IP address and Port number. The destination already has a server that accepts strings, but for some reason, the app cannot establish a socket with the server, it keeps timing out. I have only written code, so if I have to do something else like port forward on either the client or server end, please let me know.
The goal of this app is to take in a string for an IP address, a string for the Port number, and a String for the message to send to the destination. After pressing the Send button, the app will send the message to the IP and Port number defined, and display a response from the server.
This also will be used in two applications: once between the Android App and a Python server, and other between the Android App and custom hardware. Hopefully there is a solution to fit both cases.
Client Code:
public static class PlaceholderFragment extends Fragment {
TextView recieve;
EditText addressText, portText, messageText;
Button send;
Socket socket = null;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(
R.layout.fragment_customize_gateway, container, false);
recieve = (TextView) rootView.findViewById(R.id.textView1);
addressText = (EditText) rootView.findViewById(R.id.editText1);
portText = (EditText) rootView.findViewById(R.id.editText2);
messageText = (EditText) rootView.findViewById(R.id.editText3);
send = (Button) rootView.findViewById(R.id.send);
send.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AsyncSend aSend= new AsyncSend(addressText.getText().toString(),Integer.parseInt(portText.getText().toString()), messageText.getText().toString());
aSend.execute();
}
});
return rootView;
}
public class AsyncSend extends AsyncTask<Void, Void, Void> {
String address;
int port;
String message;
String response;
AsyncSend(String addr, int p, String mes) {
address = addr;
port = p;
message = mes;
}
#Override
protected Void doInBackground(Void... params) {
android.os.Debug.waitForDebugger();
Socket socket = null;
try {
System.out.println("Test");
socket = new Socket(address, port);
System.out.println("Test");
DataOutputStream writeOut = new DataOutputStream(socket.getOutputStream());
writeOut.writeUTF(message);
writeOut.flush();
ByteArrayOutputStream writeBuffer = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream writeIn = socket.getInputStream();
while((bytesRead = writeIn.read(buffer)) != -1) {
writeBuffer.write(buffer,0,bytesRead);
response += writeBuffer.toString("UTF-8");
}
} catch (UnknownHostException e){
e.printStackTrace();
response = "Unknown HostException: " + e.toString();
System.out.println(response);
} catch (IOException e) {
response = "IOException: " + e.toString();
System.out.println(response);
} finally {
if (socket != null) {
recieve.setText(response);
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
recieve.setText(response);
super.onPostExecute(result);
}
}
}
Server Code:
import http.server
import socket
import threading
import socketserver
import pymongo
import smtplib
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
#Connect to database
try:
from pymongo import MongoClient
dbclient = MongoClient()
db = dbclient.WDI_database
print("Database Connected")
except pymongo.errors.ConnectionFailure as e:
print("Database Failed: {}".format(e))
col = db.users
data2 = str(self.request.recv(1024), 'ascii')
print("Server: {}".format(data2));
data = data2.split("||")
username, password, camunits, homunits = data[0], data[1], data[2], data[3]
post = {"user": username,
"pass": password,
"cam": camunits,
"disp": homunits}
col.insert(post)
print(col.count())
cur_thread = threading.current_thread()
response = bytes("{} Received data for: {}".format(cur_thread, username), 'ascii')
self.request.sendall(response)
class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print("Recieved: " + data.decode("utf-8"))
socket.sendto(data.upper(), self.client_address)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
if __name__ == "__main__":
# Port 0 means to select an arbitrary unused port
HOST, PORT = "", 5000
tcpserver = ThreadedTCPServer((HOST, PORT-1), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=tcpserver.serve_forever)
server_thread.daemon = True
server_thread.start()
print("TCP serving at port", PORT-1)
while True:
pass
tcpserver.shutdown()
Using the Socket class is too low-level for your purposes and fraught with potential gotcha's. I suggest using org.apache.http.client.HttpClient instead.
It was probably because I didn't port forward, so my connection got blocked by my router. I opened the port on both the router and Windows.
i'm new in Android. I have the following code:
public class SettingsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tcp_settings);
Button buttonConnect = (Button) findViewById(R.id.buttonConnect);
buttonConnect.setOnClickListener(new View.OnClickListener() {
EditText server_ip = (EditText) findViewById(R.id.set_server_ip);
EditText port = (EditText) findViewById(R.id.set_port);
#Override
public void onClick(View view) {
String serverAddr = server_ip.getText().toString();
String serverPort = port.getText().toString();
new connectTask().execute(serverAddr, serverPort);
}
});
}
class connectTask extends AsyncTask<String, Void, String> {
Socket socket;
#Override
protected String doInBackground(String... params) {
int servport = Integer.parseInt(params[1]);
try {
socket = new Socket(params[0], servport);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return params[0] + " : " + params[1];
}
}
}
I want to set a socket with server ip and port getting from EditTexts server_ip and port. In the connectTask I make a conversion from string to int in: int servport but i'm still getting error:
Caused by: java.lang.NumberFormatException: Invalid int "".
i have to make serverAddr to String because i have to put it in :
new connectTask().execute(serverAddr, serverPort);
But then socket require port as Int so conversion is required.
Could You help me and tell what i'm doing wrong ?
Your problem lies here within your code. You are passing in multiple parameters into a function that only receives one. Here is the def of execute: execute (Params... params)
new connectTask().execute(serverAddr, serverPort);
Change line to this:
new connectTask().execute(new String[]{serverAddr,serverPort});
Although the documentation does not say it, it is wanting an array of the first template object being passed in IF you are passing in more than one parameter.