it's actually my first time asking a question here, and really hoping someone could give solution to my problem.
I've been working on my Design Project, and one of the feature is that it could communicate from ESP8266 NodeMCU to Android, without the NodeMCU connecting to a network. So it's like the Android connecting directly to the Wifi Module, setting up the NodeMCU as both Access Point and WebServer.
I've established a simple communication, but I want it constant and simultaneous, since i'm using this connection to display the reading of the sensor from the NodeMCU to Android. My problem here is that, it won't constantly give the values, it would only give the first data and then nothing.
Here's my Code in Android:
First is the Client Class
public class Client extends AsyncTask<Void, Void, String> {
String dstAddress;
int dstPort;
String response = "";
TextView textResponse;
Socket socket = null;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse = textResponse;
}
#Override
protected String doInBackground(Void... arg0) {
Log.d("Status_2", "Sample_2");
try {
if(socket == null)
{
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("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();
}
}
}*/
//textResponse.setText(response);
return response;
}
#Override
protected void onPostExecute(String result)
{
Log.d("Status_1", "sample");
textResponse.setText(response);
super.onPostExecute(result);
}
}
Here is from the Main Activity
public class MainActivity extends Activity {
TextView response;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear, buttonStop;
int check = 0;
public static Client myClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = findViewById(R.id.addressEditText);
editTextPort = findViewById(R.id.portEditText);
buttonConnect = findViewById(R.id.connectButton);
buttonClear = findViewById(R.id.clearButton);
buttonStop = findViewById(R.id.buttonStop);
response = findViewById(R.id.responseTextView);
myClient = new Client(editTextAddress.getText()
.toString(), Integer.parseInt(editTextPort
.getText().toString()), response);
buttonStop.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
check = 0;
}
});
buttonConnect.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
check = 1;
myClient.execute();
}
});
buttonClear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
response.setText("");
}
});
}
}
And here is the code from the Arduino:
int status = WL_IDLE_STATUS;
boolean alreadyConnected = false; // whether or not the client was connected
previously
WiFiServer server(8080);
void setup()
{
delay(1000);
Serial.begin(115200);
Serial.println();
// MotionSensor_Setup();
Serial.print("Configuring access point...");
/* You can remove the password parameter if you want the AP to be open. */
WiFi.softAP(ssid,password);
delay(10000);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.println("\nStarting server...");
// start the server:
server.begin();
}
void loop()
{
// wait for a new client:
WiFiClient client = server.available();
// when the client sends the first byte, say hello:
if(client)
{
if (!alreadyConnected)
{
// clead out the input buffer:
client.flush();
Serial.println(analogRead(A0));
Serial.println();
client.println("Hello, client!");
client.println(analogRead(A0));
delay(500);
alreadyConnected = true;
}
}
if (client.available() > 0) {
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
server.write(thisChar);
// echo the bytes to the server as well:
Serial.write(thisChar);
}
}
Eventually I've tried this code here in the void loop() method.
void loop()
{
// wait for a new client:
WiFiClient client = server.available();
// when the client sends the first byte, say hello:
while(client.connected())
{
client.println(analogRead(A0));
delay(1000);
Serial.println(analogRead(A0));
}
}
it got inside the while condition and displayed data in the Serial Monitor, but didn't displayed in the Android.
I've tried several techniques and still no luck.
I would really appreciate your reply guys, Thank you!
you can try this -> Really simple TCP client
I have doing my android server according this manual and all is work OK
Related
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 am developing Android application(online marketing), within this project i am using socket programming for communication with server, when i communicate with server if server does not give me any response within 30 sec then my asynctask will close automatically, but now problem is i want to save server response in sqlite on receiving response from server please provide me the necessary help thank
you in advance.
Here is My Asyntask :
public class SendToserver extends AsyncTask<Integer, Integer, Integer>
{
int iReturn;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progressDialog(Registartion.this, "Please Wait...");
super.onPreExecute();
}
#Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
ServerData = runm(IMEINo);
if (ServerData.equalsIgnoreCase("IsNull"))
{
iReturn = 2;
}
else {
iReturn = 1;
}
return iReturn;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
if (iReturn == 1)
{
String ServerIP = edtServerIpAddress.getText().toString();
String ServerPort = edtServerPort.getText().toString();
registartionModel = new RegistartionModel();
registartionModel.setServerIPAdreess(ServerIP);
registartionModel.setPort(ServerPort);
registrationDb = new RegistrationDb(getApplicationContext());
registrationDb.open();
registrationDb.insertData(registartionModel);
registrationDb.close();
Intent i = new Intent(getBaseContext(), LoginActivity.class);
startActivity(i);
Registartion.this.finish();
System.gc();
}
else if (iReturn == 2)
{
showDialogBox("Please Input Correct Server IP and Port");
}
super.onPostExecute(result);
}
}
My Server Communication Method(runm):
#SuppressLint("NewApi")
public String runm(String DId)
{
try {
socket = new Socket(SERVER_IP, SERVERPORT);
out = new PrintStream(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write((DId + "|" +"REG").getBytes());
ServerData = in.readLine();
System.err.println("Server Data in Runm :- " + ServerData);
if(ServerData == null || ServerData.equalsIgnoreCase(""))
{
ServerData="IsNull";
}
}
catch (NetworkOnMainThreadException e)
{
ServerData = "IsNull";
}catch (IOException ex) {
ServerData = "IsNull";
}
return ServerData;
}
Should i use Broadcast Receiver ?
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 want to develop app that connect to a server and send and receive message. i'm really beginner in that.
So,i wrote this code by This tutorial, and it seem that i get some mistake with the port or ip address beacuse i didn't get the message to the console. My inspiration is the problem is in my router setting maybe
Here is my android code (Project android)
public class MainActivity extends Activity {
Socket client;
PrintWriter printWriter;
EditText edIp,edPort,edMess;
String message;
int port = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edIp = (EditText) findViewById(R.id.edIp);
edPort = (EditText) findViewById(R.id.edPort);
edMess= (EditText) findViewById(R.id.edMessage);
edIp.setText("10.0.2.2");
edPort.setText("4444");
}
public void onClick(View v){
message = edMess.getText().toString();
edMess.setText("");
port = Integer.parseInt(edPort.getText().toString());
new Thread(new Runnable() {
#Override
public void run() {
try {
client = new Socket(edIp.getText().toString(),port);
printWriter = new PrintWriter(client.getOutputStream());
printWriter.write(message);
printWriter.flush();
printWriter.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}).start();
}
}
(java aplication)
public class Main {
public static void main(String[] args) throws IOException {
Socket clientSocket = null;
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
System.out.println("Server started...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("error" + e);
}
Scanner in1 = new Scanner(clientSocket.getInputStream());
String mess;
while (true) {
if(in1.hasNext()){
mess = in1.nextLine();
System.out.println("Client message : "+mess);
}
}
}
}