I'm trying to develop an app which needs to have modbus/TCP. The default port for Modbus/TCP is 502. I'm getting an error when I try to open a connection on port 502. I tried different ports and they were working. I think something is blocking port 502, but I couldn't figure it out.
This is the exception I'm getting: 01-01 00:01:44.309: I/System.out(953): S: Error java.net.BindException: bind failed: EACCES (Permission denied)
I have "INTERNET" permission
Code:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer extends Thread {
public static final int SERVERPORT = 502;
public boolean running = true;
public boolean receiving = false;
private PrintWriter mOut;
public TCPServer() {
}
public void sendMessage(String message) {
if (mOut != null && !mOut.checkError()) {
mOut.println(message);
mOut.flush();
}
}
#Override
public void run() {
super.run();
try {
while (true) {
while (running) {
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
serverSocket.setSoTimeout(500);
Socket tempSckt = new Socket();
boolean isConnected = false;
while (!isConnected && running) {
try {
tempSckt = serverSocket.accept();
isConnected = true;
} catch (Exception e) {
}
}
if (running) {
System.out.println("connected");
final Socket client = tempSckt;
new Thread(new Runnable() {
#Override
public void run() {
receiving = true;
try {
mOut = new PrintWriter(client
.getOutputStream());
BufferedReader in = new BufferedReader(
new InputStreamReader(client
.getInputStream()));
while (receiving) {
String message = in.readLine();
if (message != null) {
// System.out.println(message);
byte[] bytes = message.getBytes();
StringBuilder binary = new StringBuilder();
for (byte b : bytes) {
int val = b;
for (int i = 0; i < 8; i++) {
binary.append((val & 128) == 0 ? 0
: 1);
val <<= 1;
}
binary.append(' ');
}
System.out.println("'" + message
+ "' to binary: " + binary);
} else {
receiving = false;
}
}
} catch (Exception e) {
System.out.println("S: Error"
+ e.toString());
} finally {
try {
client.close();
} catch (Exception e2) {
}
}
}
}).start();
isConnected = false;
}
serverSocket.close();
}
Thread.sleep(500);
}
} catch (Exception e) {
System.out.println("S: Error " + e.toString());
}
}
}
UPDATE
My Application running as a system app. I did the necessary configurations. I checked it with ps shell command. It is working as a system app now. But still I am not able to bind to port 502.
Ports below 1024 are restricted - only apps with root privileges can listen on those. Of course, your application isn't privileged.
That's the general rule on Linux/Unix (and Android is Linux-based).
See this answer for a rationale behind this restriction.
Related
I have writing some driven tests to a flutter project and there are a barcode scanner functionality which I can test successfully using the virtual scene tool provided by android emulator.
However there are many cases to test regarding to different barcodes. I want to set a specific barcode image on virtual scene to each case. Is it possible?
I found that the value of this image is putted on ~/.android/avd/[emulatorName]/AVD.conf file at virtualscene\posters variable.
virtualscene\posters=#Variant(\0\0\0\b\0\0\0\x2\0\0\0\b\0w\0\x61\0l\0l\0\0\0\n\xff\xff\xff\xff\0\0\0\n\0t\0\x61\0\x62\0l\0\x65\0\0\0\n\xff\xff\xff\xff)
virtualscene\posters=#Variant(\0\0\0\b\0\0\0\x2\0\0\0\b\0w\0\x61\0l\0l\0\0\0\n\ 0\0\0\\\0/\0U\0s\0\x65\0r\0s\0/\0l\0\x65\0o\0n\0\x61\0r\0\x64\0o\0.\0\x61\0r\0m\0\x65\0r\0o\0/\0\x44\0\x65\0s\0k\0t\0o\0p\0/\0J\0\x61\0m\0\x65\0s\0W\0i\0l\0s\0o\0n\0.\0p\0n\0g\0\0\0\n\0t\0\x61\0\x62\0l\0\x65\0\0\0\n\xff\xff\xff\xff)
You can replace the default (global) image located at $ANDROID_SDK_HOME/emulator/resources/poster.png with your poster.png image,
nor change the default pointer by editing the file $ANDROID_SDK_HOME/emulator/resources/Toren1BD.posters.
You can set the virtual scene image to a specified path. And manipulate the target image while testing.
As the Instrumented tests are running on your (virtual) device, it cannot manipulate the host machine files directly. What can be done, (which is an ugly hack) is to start a server on the host, which can be reached from the virtual device with the hosts loop-back "10.0.2.2" address.
This server can manipulate the target files.
If anybody has better solution, please share it!
An example server and client is here.
Server:
import java.io.*;
import java.net.*;
import java.nio.channels.FileChannel;
public class FileManipulatorServer {
public static void main(String args[]) {
int port = 6789;
FileManipulatorServer server = new FileManipulatorServer( port );
server.startServer();
}
// declare a server socket and a client socket for the server
private ServerSocket fileManipulatorServer = null;
private Socket clientSocket = null;
private int port;
public FileManipulatorServer(int port ) {
this.port = port;
}
public void stopServer() {
System.out.println( "Server cleaning up." );
System.exit(0);
}
public void startServer() {
// Try to open a server socket on the given port
// Note that we can't choose a port less than 1024 if we are not
// privileged users (root)
try {
fileManipulatorServer = new ServerSocket(port);
}
catch (IOException e) {
System.out.println(e);
}
System.out.println( "Waiting for connections. Only one connection is allowed." );
// Create a socket object from the ServerSocket to listen and accept connections.
// Use FileManipulatorTask to process the connection.
while ( true ) {
try {
clientSocket = fileManipulatorServer.accept();
FileManipulatorTask task = new FileManipulatorTask(clientSocket, this);
task.run();
}
catch (IOException e) {
System.out.println(e);
}
}
}
}
class FileManipulatorTask {
private BufferedReader is;
private PrintStream os;
private Socket clientSocket;
private FileManipulatorServer server;
public FileManipulatorTask(Socket clientSocket, FileManipulatorServer server) {
this.clientSocket = clientSocket;
this.server = server;
System.out.println( "Connection established with: " + clientSocket );
try {
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public void run() {
String line;
try {
boolean serverStop = false;
line = is.readLine();
System.out.println( "Received " + line );
saveImageToPoster(line.trim());
os.println("OK");
os.flush();
System.out.println( "Connection closed." );
is.close();
os.close();
clientSocket.close();
if ( serverStop ) server.stopServer();
} catch (IOException e) {
System.out.println(e);
}
}
private void saveImageToPoster(String filename) {
try {
FileChannel src = new FileInputStream("C:\\fullpathtopostercandidates\\"+filename).getChannel();
FileChannel dest = new FileOutputStream("C:\\fullpathtoconfiguredposter\\poster.jpg").getChannel();
dest.transferFrom(src, 0, src.size());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client:
import java.io.*;
import java.net.*;
public class FileNameSenderClient {
private String hostname = "10.0.2.2";
private int port = 6789;
public void sendFileName(String filename) {
Socket clientSocket = null;
DataOutputStream os = null;
BufferedReader is = null;
try {
clientSocket = new Socket(hostname, port);
os = new DataOutputStream(clientSocket.getOutputStream());
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + hostname);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + hostname);
}
if (clientSocket == null || os == null || is == null) {
System.err.println( "Something is wrong. One variable is null." );
return;
}
try {
System.out.println("Write to output stream");
os.writeBytes( filename +"\n");
os.flush();
String responseLine = is.readLine();
System.out.println("Server returns: " + responseLine);
os.close();
is.close();
clientSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
Use the FileNameSenderClient from your instrumented test like this.
#Test
public void testQRcodeReadingOK()
{
FileNameSenderClient c = new FileNameSenderClient();
c.sendFileName("QRCode.jpg");
//your code that wants to use the image, like the this:
onView(withId(R.id.load_qr_code)).perform(click());
}
Here is a source of StreamProxy I used for my project
public class StreamProxy implements Runnable {
private static final String LOG_TAG = "Stream proxy: %s";
private int port = 0;
private boolean isRunning = true;
private ServerSocket socket;
private Thread thread;
public StreamProxy() {
init();
start();
}
public int getPort() {
return port;
}
public String getProxyUrl(String uri, String tag) {
return String.format("http://127.0.0.1:%d/%s", getPort(), uri);
}
private void init() {
try {
socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
socket.setSoTimeout(5000);
port = socket.getLocalPort();
Timber.d(LOG_TAG, "port " + port + " obtained");
} catch (IOException e) {
Timber.e(e, "Error initializing server");
}
}
private void start() {
if (socket == null) {
throw new IllegalStateException("Cannot start proxy; it has not been initialized.");
}
thread = new Thread(this);
thread.start();
}
public void stop() {
isRunning = false;
if (thread == null) {
throw new IllegalStateException("Cannot stop proxy; it has not been started.");
}
thread.interrupt();
try {
thread.join(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
Timber.d(LOG_TAG, "running");
while (isRunning) {
try {
Socket client = socket.accept();
if (client == null) {
continue;
}
Timber.d(LOG_TAG, "client connected");
client.setKeepAlive(false);
readRequest(client);
} catch (SocketTimeoutException e) {
} catch (IOException e) {
Timber.e(e, "Error connecting to client");
}
}
Timber.d(LOG_TAG, "Proxy interrupted. Shutting down.");
}
#Nullable
private void readRequest(Socket client) throws IOException {
InputStream is;
String firstLine;
try {
is = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
firstLine = reader.readLine();
} catch (IOException e) {
Timber.e(LOG_TAG, "Error parsing request", e);
return;
}
if (firstLine == null) {
Timber.i(LOG_TAG, "Proxy client closed connection without a request.");
return;
}
StringTokenizer st = new StringTokenizer(firstLine);
st.nextToken();
String uri = st.nextToken().substring(1);
Timber.d(LOG_TAG, uri);
processRequest(client, uri, "");
}
#Nullable
private HttpURLConnection download(String path) throws IOException {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage());
}
return connection;
}
private void processRequest(Socket client, String url, String tag)
throws IllegalStateException, IOException {
Timber.d(LOG_TAG, "processing");
HttpURLConnection realResponse = download(url);
if (realResponse == null) {
return;
}
InputStream data = realResponse.getInputStream();
socketWriter.setClient(client);
try {
int readBytes;
Timber.d(LOG_TAG, "writing data to client");
// Start streaming content.
byte[] buff = new byte[1024 * 8];
while (isRunning && (readBytes = data.read(buff)) != -1) {
client.getOutputStream().write(buff, 0, readBytes)
}
Timber.d(LOG_TAG, "end writing data");
} catch (IOException e) {
Timber.e(e, "Error data transfer to client");
} finally {
Timber.d(LOG_TAG, "finally block");
if (data != null) {
data.close();
}
}
}
}
It works perfectly on Android <5.0 but on Android 5.0.+ I have following error with using MediaExtractor(http://developer.android.com/reference/android/media/MediaExtractor.html)
NuCachedSource2﹕ source returned error -1, 10 retries left
NuCachedSource2﹕ source returned error -1, 9 retries left
...
And no error messages when using Mediaplayer just few quiet retries.
Maybe for Android 5 there is another way for audio streaming with caching?
Stream proxy working well actually. All errors I get from MediaExtractor was about m4a container. For most files packed in m4a format, there is no way to play it via stream by using components from Android SDK. Except some roms on Samsung, LG and some other manufactures that has this feature.
I want to make my android app open socket to my windows console app and they communicate with each other. The socket is opened and data is sent and received in windows app, but my android app does not receive the answer which sent by windows. I watch the packets in my android and I saw the packets are coming but I do not know why my app do not receive it!
windows app server class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
try
{
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
//By FMR
string response = "random responsive: " + new Random().Next(1000).ToString() + "\n";//"\r\n";
//writeData(clientStream, response);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
clientStream.Write(msg, 0, msg.Length);
clientStream.Flush();
Console.WriteLine("\nResponed ..." + response);
}
}
catch (Exception ex)
{
Console.WriteLine("\nException while: " + ex.Message);
}
tcpClient.Close();
}
}
my android thread:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
ServerSocket serverSocket = null;
Boolean bRun = true;
try {
socket = new Socket(ip, port);
if(outputStream == null) {
outputStream = new DataOutputStream(socket.getOutputStream());
}
// become server
serverSocket = new ServerSocket(port);
Log.i(G.TAG, "before serverSocket.accept");
socket = serverSocket.accept();
Log.i(G.TAG, "response recieve: ");
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
try {
serverSocket.close();
} catch (IOException e1) {
Log.e(G.TAG, "serverSocket.close() e: " + e1.getMessage());
}
try {
socket.close();
} catch (IOException e1) {
Log.e(G.TAG, "socket.close() e: " + e1.getMessage());
}
}
Log.i(G.TAG, "after start recieve: ");
while (bRun) {
try {
Log.i(G.TAG, "while start: ");
String message = inputStream.readLine();
Log.i(G.TAG, "response message: " + message);
if (message != null) {
setListMessage(false, message);
}
}
catch (IOException e) {
bRun = false;
Log.e(G.TAG, "while bRun e: " + e.getMessage());
}
}
}
});
thread.start();
// in another function, my message is sent successfully from android and receive in windows
I found the problem, this line
socket = serverSocket.accept();
made the problem when I comment the line, the android app received the response!
Does anybody know why?
I'm making an Android App to communicate with a computer windows.
I found that it must be easy to do that by forwarding the port with ADB commands.
So i try to make a client/server connection over USB but i have some problems
my server on Windows:
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("EchoClient.main()");
Socket client = null;
// initialize server socket
try {
server = new ServerSocket(38300);
server.setSoTimeout(TIMEOUT * 1000);
// attempt to accept a connection
client = server.accept();
Globals.socketOut = new PrintStream(client.getOutputStream());
Globals.socketIn = new BufferedReader(new InputStreamReader(client.getInputStream()));
// Globals.socketIn.YY
} catch (SocketTimeoutException e) {
// print out TIMEOUT
connectionStatus = "Connection has timed out! Please try again";
System.out.println(connectionStatus);
} catch (IOException e) {
System.out.println("error"+ e);
} finally {
// close the server socket
try {
if (server != null)
server.close();
} catch (IOException ec) {
System.out.println("Cannot close server socket"+ ec);
}
}
if (client != null) {
System.out.println("connected");
}
}
public static class Globals {
private static String typeOfTransmission ;
static PrintStream socketOut = null;
static BufferedReader socketIn = null;
public static synchronized String getTypeTransmission(){
return typeOfTransmission;
}
public static synchronized void setTypeTransmission(String s){
typeOfTransmission = s;
}
}
}
android APP client
private Runnable initializeConnection = new Thread() {
public void run() {
Socket client = null;
// initialize server socket
try {
Log.d("ip",getLocalIpAddress());
client = new Socket(getLocalIpAddress(), 38300);
Globals.socketIn = new Scanner(new InputStreamReader(
client.getInputStream()));
Globals.socketOut = new PrintWriter(client.getOutputStream());
// Globals.socketIn.YY
} catch (SocketTimeoutException e) {
// print out TIMEOUT
connectionStatus = "Connection has timed out! Please try again";
mHandler.post(showConnectionStatus);
} catch (IOException e) {
Log.e(TAG, "" + e);
} finally {
// close the server socket
try {
if (server != null)
server.close();
} catch (IOException ec) {
Log.e(TAG, "Cannot close server socket"+ ec);
}
}
if (client != null) {
Globals.connected = true;
// print out success
connectionStatus = "Connection was succesful!";
Log.d(TAG, "connected!");
mHandler.post(showConnectionStatus);
while (Globals.socketIn.hasNext()) {
socketData = Globals.socketIn.next();
mHandler.post(socketStatus);
}
}
}
};
public String getLocalIpAddress(){
try{
for(Enumeration<NetworkInterface> en =NetworkInterface.getNetworkInterfaces();en.hasMoreElements();){
NetworkInterface intf = en.nextElement();
for(Enumeration<InetAddress> enumIpAddress= intf.getInetAddresses();enumIpAddress.hasMoreElements();){
InetAddress inetAddress = enumIpAddress.nextElement();
if (!inetAddress.isLoopbackAddress()){
return inetAddress.getHostAddress().toString();
}
}
}
}catch(SocketException ex){
Log.e("ServerActivity",ex.toString());
}
return null;
}
Logger
01-29 11:43:49.640: D/ip(2981): fe80::a806:ff:fec6:d3d%p2p0
01-29 11:43:49.650: E/Connection(2981): java.net.ConnectException: failed to connect to /fe80::a806:ff:fec6:d3d%p2p0%4 (port 38300): connect failed: ECONNREFUSED (Connection refused)
thank you
The server should send a message "Hello :: enter QUIT to exit" to the client, then the client types in any text and the server echos back the client's text adding "From server: " before their message.
But there seems to be a mix up in the order and I can't seem to find where! I've been on this all day!
This is the Server's code:
import java.net.*;
public class Server {
public static void main(String[] args) {
int nreq = 1;
try
{
ServerSocket sock = new ServerSocket (8080);
for (;;)
{
Socket newsock = sock.accept();
System.out.println("Creating thread ...");
Thread t = new ThreadHandler(newsock,nreq);
t.start();
}
}
catch (Exception e)
{
System.out.println("IO error " + e);
}
System.out.println("End!");
}
}
ThreadHandler code:
import java.io.*;
import java.net.*;
class ThreadHandler extends Thread {
Socket newsock;
int n;
ThreadHandler(Socket s, int v) {
newsock = s;
n = v;
}
// #SuppressWarnings("deprecation")
public void run() {
try {
PrintWriter outp = new PrintWriter(newsock.getOutputStream(), true);
BufferedReader inp = new BufferedReader(new InputStreamReader(
newsock.getInputStream()));
outp.println("Hello :: enter QUIT to exit");
boolean more_data = true;
String line;
while (more_data) {
line = inp.readLine();
if (line == null) {
more_data = false;
} else {
outp.println("From server: " + line + "\n");
if (line.trim().equals("QUIT"))
more_data = false;
}
}
newsock.close();
} catch (Exception e) {
System.out.println("IO error " + e);
}
}
}
And the Client code:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Client {
// #SuppressWarnings("deprecation")
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
try {
Socket s = new Socket("localhost", 8080);
PrintWriter outp = new PrintWriter(s.getOutputStream(), true);
BufferedReader inp = new BufferedReader(new InputStreamReader(
s.getInputStream()));
boolean more_data = true;
System.out.println("Established connection");
String line;
while (more_data) {
line = inp.readLine();
String userInput = scanner.nextLine();
outp.println(userInput);
if (line == null) {
more_data = false;
} else
System.out.println(line);
}
System.out.println("end of while");
} catch (Exception e) {
System.out.println("IO error " + e);
}
}
}
I'm testing it out so after I'm going to make the client an Android phone - if that's possible -
Update:
I've changed the server's code to:
outp.println("Hello :: enter QUIT to exit \n");
boolean more_data = true;
String line;
while (more_data) {
line = inp.readLine();
System.out.println("Message '" + line + "' echoed back to client.");// !!
if (line == null) {
System.out.println("line = null");
more_data = false;
} else {
outp.println("From server: " + line + ". \n");
if (line.trim().equals("QUIT"))
more_data = false;
}
}
newsock.close();
System.out.println("Disconnected from client number: " + n);
and added "\n" at the end of the Hello message as Luis Miguel Serrano suggested, And changed the Client's side as below:
boolean more_data = true;
System.out.println("Established connection");
String line;// = inp.readLine();
while (more_data) {
line = inp.readLine();
System.out.println(line);
if (line == null) {
// nothing read
more_data = false;
} else
line = inp.readLine();
System.out.println(line);
String userInput = scanner.nextLine();
if (userInput.trim() == "QUIT") {
s.close();
System.out.println("Disconnected from server.");
more_data = false;
} else
outp.println(userInput);
}
System.out.println("end of while");
And it works fine now.
If anyone could suggest me some Android client-java server tutorials would appreciate it.
In sequence of your comment, it could be a flushing issue. Try adding the following line:
outp.flush();
after:
outp.println("Hello :: enter QUIT to exit");
When you write to a stream, sometimes the things you write are kept in a buffer. If you want to make sure that buffer is emptied and the string is actually sent, you need to call the flush() method.
Update
Also, add "\n" to the end of your Hello welcome message from the server. I think that will make it work.