I am trying to relay a message from a Servlet to COM in raspberry pi on Tomcat 7.
I am using null cable between raspberry and my PCs to test.
I am using jssc API (Java Simple Serial Connector) for serial communication.
Raspberry pi is using JDK 1.8.0_65.
I am getting the message in UTF8 and I should output it in ISO8859-7.
Since UTF8 is a superset of ISO8859-7, the app that calls the servlet ensures all characters sent are legitimate for ISO8859-7.
My code:
package com.test.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import jssc.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(value = "/Relay", name = "Relay")
public class Relay extends HttpServlet {
static Logger app = null;
static {
app = Logger.getLogger("com.test.app");
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,HttpServletResponse response) {
try {
request.setCharacterEncoding("ISO-8859-7");;
response.setCharacterEncoding("ISO-8859-7");
//request.setCharacterEncoding("UTF-8");
//response.setCharacterEncoding("UTF-8")
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String message = request.getParameter("message");
app.logp(Level.INFO, this.getClass().getCanonicalName(),"APP", message);
String[] portNames = SerialPortList.getPortNames();
app.logp(Level.INFO, this.getClass().getCanonicalName(),"APP", portNames.length+"");
for(int i = 0; i < portNames.length; i++){
applogp(Level.INFO, this.getClass().getCanonicalName(),"APP", portNames[i]);
byte[] msg = new byte[1024];
msg = message.getBytes("ISO-8859-7");
Charset utf8charset = Charset.forName("UTF-8");
Charset iso88597charset = Charset.forName("ISO-8859-7");
ByteBuffer inputBuffer = ByteBuffer.wrap(message.getBytes());
CharBuffer data = utf8charset.decode(inputBuffer);
ByteBuffer outputBuffer = iso88597charset.encode(data);
byte[] outputData = outputBuffer.array();
byte[] b1 = message.getBytes();
byte[] b2 = message.getBytes(Charset.forName("ISO-8859-7"));
byte[] b3 = message.getBytes(StandardCharsets.ISO_8859_1);
SerialPort serialPort = new SerialPort((portNames[i]));
try {
serialPort.openPort();
serialPort.setParams(SerialPort.BAUDRATE_9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
serialPort.writeBytes(msg);
serialPort.writeBytes(message.getBytes());
serialPort.writeBytes(outputData);
serialPort.writeBytes(b1);
serialPort.writeBytes(b2);
serialPort.writeBytes(b3);
serialPort.closePort();
} catch (SerialPortException ex) {
app.logp(Level.INFO, this.getClass().getCanonicalName(),"APP", ex.getMessage());
out.write("NOK");
out.close();
}
}
out.write("OK");
out.close();
} catch (IOException e) {
app.logp(Level.INFO, this.getClass().getCanonicalName(),"APP", e.getMessage());
}
}
private static final long serialVersionUID = 1L;
}
The problem is that when I am testing I do not get valid output in putty.
putty output
I have configured putty to display ISO8859-7 characters.
Any for changes ?
What am I missing ?
Thanks in advance.
I tried to divide the problem by producing the following code:
import java.io.UnsupportedEncodingException;
import jssc.SerialPort;
import jssc.SerialPortException;
public class SerialTest {
public static void main(String[] args) {
String message = "message μήνυμα";
if ( sendTextOnCom(message) ) {
System.out.println("SUCCESS MESSAGE SENT");
}
else{
System.out.println("FAIL MESSAGE NOT SENT");
}
}
private static boolean sendTextOnCom(String message) {
boolean isOverlaid = false;
SerialPort com = null;
try {
String comNo = "COM1"; // String comNo="/dev/ttyUSB0"; //when used in Raspberry
com = new SerialPort(comNo);
com.openPort();
com.setParams(9600, 8, 1, 0);
com.writeString(message);
com.writeBytes(message.getBytes("ISO-8859-7"));
com.closePort();
isOverlaid = true;
}
catch (SerialPortException ex) {
System.out.println("[ERROR] COM ERROR SENDING MESSAGE");
isOverlaid = false;
try {
com.closePort();
} catch (SerialPortException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return isOverlaid;
}
}
The code is working normally in Windows 7 64bit and it is producing output in putty with the right characters.
When I compile and run the same code in raspberry PI the output in putty is not showing the valid characters.
I tend to think that it's a raspberry PI configuration issue.
Related
Flink can read a socket stream, can it read http requests? how?
// socket example
DataStream<XXX> socketStream = env
.socketTextStream("localhost", 9999)
.map(...);
There's an open JIRA ticket for creating an HTTP sink connector for Flink, but I've seen no discussion about creating a source connector.
Moreover, it's not clear this is a good idea. Flink's approach to fault tolerance requires sources that can be rewound and replayed, so it works best with input sources that behave like message queues. I would suggest buffering the incoming http requests in a distributed log.
For an example, look at how DriveTribe uses Flink to power their website on the data Artisans blog and on YouTube.
I write one custom http source. please ref OneHourHttpTextStreamFunction. you need create a fat jar to include apache httpserver classes if you want run my code.
package org.apache.flink.streaming.examples.http;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.examples.socket.SocketWindowWordCount.WordWithCount;
import org.apache.flink.util.Collector;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.bootstrap.HttpServer;
import org.apache.http.impl.bootstrap.ServerBootstrap;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.apache.flink.util.Preconditions.checkArgument;
import static org.apache.flink.util.Preconditions.checkNotNull;
public class HttpRequestCount {
public static void main(String[] args) throws Exception {
// the host and the port to connect to
final String path;
final int port;
try {
final ParameterTool params = ParameterTool.fromArgs(args);
path = params.has("path") ? params.get("path") : "*";
port = params.getInt("port");
} catch (Exception e) {
System.err.println("No port specified. Please run 'SocketWindowWordCount "
+ "--path <hostname> --port <port>', where path (* by default) "
+ "and port is the address of the text server");
System.err.println("To start a simple text server, run 'netcat -l <port>' and "
+ "type the input text into the command line");
return;
}
// get the execution environment
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// get input data by connecting to the socket
DataStream<String> text = env.addSource(new OneHourHttpTextStreamFunction(path, port));
// parse the data, group it, window it, and aggregate the counts
DataStream<WordWithCount> windowCounts = text
.flatMap(new FlatMapFunction<String, WordWithCount>() {
#Override
public void flatMap(String value, Collector<WordWithCount> out) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (String word : value.split("\\s")) {
out.collect(new WordWithCount(word, 1L));
}
}
})
.keyBy("word").timeWindow(Time.seconds(5))
.reduce(new ReduceFunction<WordWithCount>() {
#Override
public WordWithCount reduce(WordWithCount a, WordWithCount b) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new WordWithCount(a.word, a.count + b.count);
}
});
// print the results with a single thread, rather than in parallel
windowCounts.print().setParallelism(1);
env.execute("Http Request Count");
}
}
class OneHourHttpTextStreamFunction implements SourceFunction<String> {
private static final long serialVersionUID = 1L;
private final String path;
private final int port;
private transient HttpServer server;
public OneHourHttpTextStreamFunction(String path, int port) {
checkArgument(port > 0 && port < 65536, "port is out of range");
this.path = checkNotNull(path, "path must not be null");
this.port = port;
}
#Override
public void run(SourceContext<String> ctx) throws Exception {
server = ServerBootstrap.bootstrap().setListenerPort(port).registerHandler(path, new HttpRequestHandler(){
#Override
public void handle(HttpRequest req, HttpResponse rep, HttpContext context) throws HttpException, IOException {
ctx.collect(req.getRequestLine().getUri());
rep.setStatusCode(200);
rep.setEntity(new StringEntity("OK"));
}
}).create();
server.start();
server.awaitTermination(1, TimeUnit.HOURS);
}
#Override
public void cancel() {
server.stop();
}
}
Leave you comment, if you want the demo jar.
After hours of trawling the internet and trying to make sense of the documentation I seem unable to find a resolution to this problem.
I have an application which is using an ASyncTask to connect to a server I have 3 addresses to "test" the connection.
Now the problem is when I use the Myconnection.connect() the background task just hangs if there is either no known address or a dead link.
How can I test this connection when with a dead link or dead server it hangs and does not receive any response
The errors in the Logcat are
07-02 12:47:13.101 13850-20562/nodomain.myapplication D/URL ERRORhttp://10.0.0.2/testdb/connection.php
07-02 12:47:13.339 13850-20562/nodomain.myapplication I/URL IS OK: [ 07-02 12:47:13.339 13850:20562 I/ ]Status : 200
07-02 12:47:13.344 13850-20562/nodomain.myapplication D/URL ERRORhttp://localhost/myPage.php
As you can see the only URL I get a response from is www.google.com
My code is below:
package nodomain.myapplication;
import android.os.AsyncTask;
import android.util.Log;
import org.w3c.dom.Text;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
/**
* Created by Shab on 02/07/2017.
*/
public class bgWorker extends AsyncTask<Void, Integer, Void> {
#Override
protected Void doInBackground(Void... params)
{
String db_Username = "root";
String db_Password = "";
String db_Name = "testdb";
String url1 = "http://10.0.0.2/testdb/connection.php"; //DEAD? (NO RESPONSE)
(Program Hang until exception is called)
String url2 = "http://www.google.com"; //OK RESPONSE 200
String url3 = "http://localhost/myPage.php"; //NO RESPONSE
try {
getResponseCodes(url1);
getResponseCodes(url2);
getResponseCodes(url3);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
}
private String encodeURLString(String value) {
String encodedString = "";
try {
encodedString = URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodedString;
}
public static int getResponseCodes(String TheURL) throws MalformedURLException,IOException
{
URL oUrl = new URL(TheURL);
HttpURLConnection oHuC = (HttpURLConnection) oUrl.openConnection();
oHuC.setRequestMethod("HEAD");
int response = 0;
try{
oHuC.connect();
response = oHuC.getResponseCode();
if(response == 200)
{
Log.i("URL IS OK","");
}else{
Log.i("URL IS NOT OK","");
}
Log.i("", "Status : " + response);
}catch(IOException e){
Log.d("URL ERROR" + oUrl, "D");
}
return response;
}
}
Even with the IF statement testing the response for a 200 OK it only manages to interpret one response from the 3 URL due to the URL IS OK output.
I have set up a network and I've set up the reading and writing stream to a socket as so:
//Set up socket reads and writes
final BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
final PrintWriter out = new PrintWriter(
client.getOutputStream(), true);
I wanted to pass the two variables, 'in' and 'out', as parameters of another class' constructor. This is how it looks in the other class
BufferedReader in;
PrintWriter out;
public ClientThread(BufferedReader in, PrintWriter out) {
this.in = in;
this.out = out;
}
I then wanted to use those class variables to write to the output stream of the same socket like this (the class implements Runnable):
public void run() {
while (true) {
try {
String userCommand = in.readLine();
} catch (IOException e) {
// Die if something goes wrong.
System.err.println(e.toString());
System.exit(1);
}
}
}
However, whenever the code gets to this point, I get a SocketException:
java.net.SocketException: Socket closed
How can I fix this? I want to separate the setting up of the server and the socket from the processing of any commands given by the client.
EDIT: Here's what the BufferedRead gets the input from
//create server socket
ServerSocket server = new ServerSocket(portNum);
// Accept a client if it appears
Socket client = server.accept();
EDIT 2: I used these three files:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//Change the socket if it doesn't work
Socket sock = new Socket("localhost", 5920);
//keyboard
final BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
//input from socket
final BufferedReader in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
//writer to socket
final PrintWriter out = new PrintWriter(
sock.getOutputStream(), true);
//new thread for incoming messages
(new Thread(){
#Override
public void run() {
String serverMessage;
try {
while ((serverMessage = in.readLine()) != null) {
System.out.println(serverMessage);
}
} catch (IOException e) {
System.err.println("Something went wrong whilst trying "
+ "to retrieve a message from the server");
System.exit(-1);
}
}
}).start();
//new thread for outgoing messages
(new Thread(){
#Override
public void run() {
String clientMessage;
try {
while ((clientMessage = stdin.readLine()) != null) {
out.println(clientMessage);
}
} catch (IOException e) {
System.err.println("Something went wrong whilst trying "
+ "to send a message to the server.");
System.exit(-1);
}
}
}).start();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(5920);
Socket client = server.accept();
//Set up socket reads and writes
final BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
final PrintWriter out = new PrintWriter(
client.getOutputStream(), true);
new Thread(new ClassWithParam(in, out)).start();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
public class ClassWithParam implements Runnable {
BufferedReader in;
PrintWriter out;
public ClassWithParam(BufferedReader in, PrintWriter out) {
this.in = in;
this.out = out;
}
#Override
public void run() {
while (true) {
try {
System.out.println("HERE");
String userCommand = in.readLine();
System.out.println("HERE2");
} catch (IOException e) {
// Die if something goes wrong.
System.err.println(e.toString());
System.exit(1);
}
}
}
}
And now it works. Don't know what happened. Will proceed to bang head against wall. Thanks.
For some reason there's no problem now. The code (I recreated) which I used, which now works, is in the description.
I am currently writing this code for my client and server,
and I want to test it out using my emulator, but I'm stuck.
is this the correct IP address that I should be using?
socket = new Socket("10.0.2.2", 6000);
If i want to use my phone to test this out, what ip address should i be using?
thanks.
if you want to send messages between server/client, here is a sample code that i have made before.
please refer to the code below and feel free to comment!
also, that is the correct ip address to use when using emulator for simulation.
in addition, don't forget to change your permission to "android.permission.INTERNET" in your manifesto.
=================================myClient==================================
package com.example.myclient;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
/** Manifest --> uses permission --> "android.permission.INTERNET" */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
class MyThread extends Thread {
#Override
public void run() {
super.run();
Log.d("client", "thread is running...");
String str = "Do you want to eat hamburger?";
Socket socket;
try {
socket = new Socket("10.0.2.2", 6000);
ObjectOutputStream out = new ObjectOutputStream(socket
.getOutputStream());
ObjectInputStream in = new ObjectInputStream(
socket.getInputStream());
out.writeObject(str);
String rcv = (String) in.readObject();
Log.d("client", "Server :" + rcv);
out.close();
in.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
MyThread t = new MyThread();
t.start();
}
});
}
}
============================MyServer========================================
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket server = new ServerSocket(6000);
System.out.println("waiting.....");
while (true) {
Socket socket = server.accept();
System.out.println("a client has connected...");
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
ObjectInputStream objIn = new ObjectInputStream(in);
ObjectOutputStream objOut = new ObjectOutputStream(out);
String str = (String) objIn.readObject();
System.out.println("client : " + str);
objOut.writeObject("No, I'm on a diet!!!");
objIn.close();
objOut.close();
socket.close();
}
}
}
10.0.2.2 will be the correct IP you are using emulator. 127.0.0.1 will be the IP if you are developing on the machine(client and server on same machine). As you said you want to test it in your mobile run the following code and you will get your IP(it will also work if you are on computer):
public class net
{
net() throws UnknownHostException
{
InetAddress ia=InetAddress.getLocalHost();
System.out.println(ia);
ia=InetAddress.getByName("local host");
System.out.println(ia);
}
public static void main(String args[])throws UnknownHostException
{
net a=new net();
}
}
The overall topic is actually like a Chat Application sending a simple string message to an aws server, which uses the message to make calculations server-side and sending a simple string message as a solution back to the client.
Server: I have written a Server Class and deployed it through eclipse to aws beanstalk. (see code Server)
Client: My android device creates a socket, establishes a successful connection to my aws beanstalk ip and 8080 port, while iterating through an endless while loop in a thread listening to incoming messages from the server. (see code Client and ClientThread)
Problem: My problem is that I don't know how to check whether the server receives the connection request and messages from the client. How do I make sure, that code on aws beanstalk actually runs in background continuously listening for incoming connections? I have deployed the code, does aws beanstalk automatically start the main method of the Server Class and runs it infinitely?
Here's the server code:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) {
ServerSocket server = null;
System.out.println("Trying to open serversocket!");
try {
server = new ServerSocket(8080);
} catch (IOException e) {
System.out.println("Error on port: 8080 " + ", " + e);
System.exit(1);
}
System.out
.println("Server setup and waiting for client connection ...");
Socket client = null;
try {
client = server.accept();
} catch (IOException e) {
System.out.println("Did not accept connection: " + e);
System.exit(1);
}
System.out
.println("Client connection accepted. Moving to local port ...");
try {
DataInputStream streamIn = new DataInputStream(
new BufferedInputStream(client.getInputStream()));
DataOutputStream streamOut = new DataOutputStream(
new BufferedOutputStream(client.getOutputStream()));
boolean done = false;
String line;
int i = 4;
while (!done) {
line = streamIn.readUTF();
if (line.equalsIgnoreCase(".bye"))
done = true;
else
System.out.println("Client says: " + line);
if (i == 4) {
streamOut
.writeUTF("Actually connected to Server with round "
+ i);
streamOut.flush();
i++;
}
}
streamIn.close();
streamOut.close();
client.close();
server.close();
} catch (IOException e) {
System.out.println("IO Error in streams " + e);
}
}
}
Here's the client code:
package com.amazon.aws.singlesensor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.util.Log;
class Client implements Runnable {
private Socket socket = null;
private InputStream streamIn = null;
private OutputStream streamOut = null;
public InputStream getStreamIn() {
return streamIn;
}
public Client(String serverName, int serverPort) {
System.out.println("Establishing connection. Please wait ...");
try {
socket = new Socket(serverName, serverPort);
Log.d("DEBUG", "Connected: " + socket);
start();
} catch (UnknownHostException uhe) {
Log.d("DEBUG", "Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
Log.d("DEBUG", "Unexpected exception: " + ioe.getMessage());
}
}
public void start() throws IOException {
streamIn = socket.getInputStream();
streamOut = socket.getOutputStream();
}
public void run() {
try {
streamOut.write(streamIn.read());
streamOut.flush();
} catch (IOException ioe) {
System.out.println("Sending error: " + ioe.getMessage());
stop();
}
}
public void handle(String msg) {
if (msg.equals(".bye")) {
System.out.println("Good bye. Press RETURN to exit ...");
stop();
} else
System.out.println(msg);
}
public void stop() {
try {
if (streamIn != null)
streamIn.close();
if (streamOut != null)
streamOut.close();
if (socket != null)
socket.close();
} catch (IOException ioe) {
System.out.println("Error closing ...");
}
}
public void send(String msg) {
PrintWriter printwriter = new PrintWriter(streamOut);
printwriter.write(msg);
printwriter.flush();
}
}
Here's the ClientThread Code
package com.amazon.aws.singlesensor;
import java.io.IOException;
import java.io.InputStream;
import android.os.Handler;
public class ClientThread extends Thread {
private Client client;
private InputStream input;
private String output;
private Handler handler;
private Runnable runner;
public ClientThread() {
}
public ClientThread(Client client, Handler handler, Runnable runner) {
this.setClient(client);
this.input = client.getStreamIn();
this.handler = handler;
this.runner = runner;
this.output = "";
}
public void run() {
int status = 0;
while (status != -1) {
try {
status = input.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (status != '~'){
try {
status = input.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
output = output + String.valueOf((char) status);
handler.post(runner);
}
output = output + "\n";
}
}
public String giveString(){
return output;
}
public void setClient(Client client) {
this.client = client;
}
public Client getClient() {
return client;
}
}
Thank you for your time!