Web dynamic project, Instance the same instance - java

I'm working on a web project, I have a class named Connection, this class establishes a connection via TCP/IP with another device, When there is a http get request I instance an object "connection_o" and start a thread to keep the communication up like this: "connection_o.start" so the connection is established, in the next http request I must send a message, but when I execute again the "doGet" in order to avoid the nullpointer exception I need to instance the object again , but I can't because I need to use the same instance that I used before that is running, in my tests, the connection keeps working but I´m unable to access to the thread I already created. So I need some kind of static class or a way to use the thread that is already running.
This is the code for the socket
import java.io.*;
import java.net.*;
public class Provider extends Thread{
ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Provider(){}
public void run()
{
try{
//1. creating a server socket
providerSocket = new ServerSocket(2004, 10);
//2. Wait for connection
System.out.println("Waiting for connection");
connection = providerSocket.accept();
System.out.println("Connection received from " + connection.getInetAddress().getHostName());
//3. get Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
//4. The two parts communicate via the input and output streams
do{
try{
message = (String)in.readObject();
// System.out.println("client>" + message);
if (message.equals("cambio la variable"))
System.out.println("Abriendo Puerta");
// sendMessage("bye");
}
catch(ClassNotFoundException classnot){
System.err.println("Data received in unknown format");
}
}while(!message.equals("bye"));
}
catch(IOException ioException){
ioException.printStackTrace();
}
finally{
//4: Closing connection
try{
in.close();
out.close();
providerSocket.close();
}
catch(IOException ioException){
ioException.printStackTrace();
}
}
}
public void sendMessage(String msg)
{
try{
out.writeObject(msg);
out.flush();
// System.out.println("server>" + msg);
}
catch(IOException ioException){
ioException.printStackTrace();
}
}
This is the doGet
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String s = request.getParameter("s");
//Routine to send blink to RPi
if (s.equals("Start")){
Provider c = new Provider();
c.Inicio();
}
if (s.equals("Send")){
c.sendMessage("Blink");
}
Thanks in advance

The problem I assume is, that HTTP is a stateless protocol. That means by default the server does not know anything about the client.
That is where Sessionscome in place. On your initial request you have to initialize a session for the client who made the request. From then you are able to "recognize" the client on requests (e.g. to restore the clients state).
You also have to save the "connection" inside the session context. You may want to consider using so called "Connection Pools" because it could be very complicated to handle all established connection and close them properly (e.g. session timeout etc.)
I suggest you read basics about the HTTP protocol, Sessions and (e.g. Database)Connetion-Handling.

May be you can keep the
Provider c = new Provider();
as an instance variable of the servlet class and change the code :
if (s.equals("Start")){
c.Inicio();
}
Note : In this case you need to take care of the thread safety. Because now c.Inicio() would be called by multiple request threads at a time.

Related

How to control the printwriter from a separate method?

Im working on building my own GUI program that talks to my pc from a tablet. I have the server side done in java but my problem is on the client side.
I want to send data out the PrintWriter to the server from a separate method.
I have accomplished sending in the code below (it sends 'a') but i cant figure out how to send it from a separate method. i believe its a basic java scope problem that im not understanding. i would really appreciate the help.
I have tried moving the variables into other scopes.
import java.io.*;
import java.net.*;
public class TestClient {
public static void main(String[] args) {
String hostName = "192.168.0.3";
int portNumber = 6666;
try ( //Connect to server on chosen port.
Socket connectedSocket = new Socket(hostName, portNumber);
//Create a printWriter so send data to server.
PrintWriter dataOut = new PrintWriter(connectedSocket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
) {
//Send data to server.
dataOut.println("a");
}catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
public static void sendToServer() {
//I want to control the print writer from this method.
//I have failed i all the ways i have tried.
}
}
You could move the Printer-Code (try try block) into the sendToServer-method and call it via
TestClient client = new TestClient();
client.sendToServer("this is a test");
Of course the sendToServer method needs to accept a parameter then. Even better would probably be to put the main method into a Starter class and decouple it from the Client-Class that you use for sending the data.

Client Server communication in Java: how to distinguish between sockets

I'm now processing a client-server communication in Java, by using Socket and ServerSocket objects.
Once the server has been initialised, it puts on hold with new clients through the accept() method, from ServerSocket class; I immediately provide to put this socket in a client map on the server:
- keys: ClientNode(Socket s, CommunicationChannels channels);
- values: Info();
(CommunicationChannels contains ObjectOutputStream and ObjectInputStream from socket; Info contains some information about client, as username, messages etc..).
Given that, at the very beginning, the socket does not have any other information on the client besides the socket itself, first insertion on the map is map.put(ClientNode, null). I will fill the field "value" afterwards.
Now, on Client class, I am going to initialise a Socket("127.0.0.1", 13001), namely with a loopback address and gate 13001. Once communication channels have been initialised, client connects to the server.
Once the client starts, he takes a remote copy of the server through RMI (stub) libraries and the server makes a register() method available: it would allow to use this method to write requested information (from the clients) on the map.
How can the client go back to the socket with which it has been registered on the server? Frankly speaking, I supposed that accept() method from ServerSocket could take the socket established on the startup client back to the server, namely with the new Socket("127.0.0.1", 13001), but it seems to me that this does not happen.
Here you can find parts of the code, so you can better understand what I'm talking about. I've already taken into account a few things that I will share with you in case of need.
public class Server implements Runnable, RemoteServices {
...
private Map<ClientNode, Info> map = new HashMap<ClientNode, Info>();
...
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket();
while (true) {
if (!ss.isBound()) {
ss.bind(new InetSocketAddress(ipServer, port));
}
Socket client = ss.accept();
CommunicationChannels channels = new CommunicationChannels(new ObjectOutputStream(client.getOutputStream()), new ObjectInputStream(client.getInputStream()));
map.put(new ClientNode(client, channels), null);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// RemoteServices implementa Remote e mette a disposizione register()
public void register(Info info) throws RemoteException {
// TODO
}
public class Client implements Runnable {
...
...
#Override
public void run() {
Socket client = null;
try {
client = new Socket(ipServer, port);
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
Registry registry = LocateRegistry.getRegistry("127.0.0.1");
stub = (RemoteServices) registry.lookup("remoteObject");
Info info = new Info();
info.setID(getID());
info.setUsername("Giordano");
stub.register(info);
} catch (IOException e) {
System.err.println("Spiacente: il server ha terminato l'esecuzione.");
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
Remarks:
I have not included the code of some classes because I thought it was superfluous; for example the "info" class is just a series of "getter and setter" of some fields; the CommunicationChannels class represents communication channels of the client, taken directly from the socket, etc ..
The server, after the accept(), does not instantiate any thread to communicate with the client because communication has to come afterwards. However, if there was a way to solve my problem with a thread of communication I would find a way to fix it.
My question starts from the need to make interact 2 clients with a server without using more PCs; therefore all clients will have the IP loopback and therefore I cannot use the IP address as a discriminating between two sockets, otherwise I would have already solved it.
In other words, I know that methods as socket.getInetAddress().getHostAddress() can help me to distinguish between two socket, but if I initialise two clients on the same PC I have to use loopback address and the method always returns "127.0.0.1".
The register() method is obviously incomplete even in the signature; once understood how to compare the server socket and client one through a Serializable discriminating object (like the hashcode()) probably I might put it in the arguments of the method, so you can easily make the comparison.
Finally, main() methods:
public static void main(String[] args) {
Server server = new Server("127.0.0.1", 13001);
RemoteServices stub;
try {
stub = (RemoteServices) UnicastRemoteObject.exportObject(server, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("remoteObject", stub);
(new Thread(server)).start();
} catch (RemoteException e) {
System.err.println("Verificare l'apertura dei registri");
} catch (AlreadyBoundException e) {
System.err.println("Server già attivo. Controllare che i registri siano chiusi correttamente.");
}
}
public static void main(String[] args) { Client client = new Client("127.0.0.1", 13001);
new Thread(client).start();
}
I really hope everything is clear and that you can help me.

Reading Data from Bluetooth Data Transfer on Android

I am looking to get/read the Data I passed after I connected a couple of Android Devices, so far I pair, connect and transmit the information between them, but not sure how to implement the reading part, here I am not sure if I should use createRfcommSocketToServiceRecord or listenUsingRfcommWithServiceRecord to create the reading socket for this purpose.
I have two screens, one where the user push a button and transmit the info and the other where the receiver press another button and read the data, I wonder if the sync is incorrect and after I push the "send" button and then the "read" button the connection is unavailable or if this implementation is just not recomendable all together.
These are my two attempts:
Attempt 1:
//Executed after the user press the read data button
private void connectToServerSocket(BluetoothDevice device, UUID uuid) {
try{
BluetoothServerSocket serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(device.getName(),uuid);
//Here is where I get the error:
//io to Server Socket JSR82 Connection is not created, failed or aborted
BluetoothSocket clientSocket = serverSocket.accept();
// Start listening for messages.
StringBuilder incoming = new StringBuilder();
listenForMessages(clientSocket, incoming);
// Add a reference to the socket used to send messages.
transferSocket = clientSocket;
} catch (IOException ioe) {
this.printToast("Excep io toServerSocket:" + ioe.getMessage());
} catch (Exception e) {
this.printToast("Excep toServerSocket:" + e.getMessage());
}
}
Attempt 2:
private void connectToServerSocket(BluetoothDevice device, UUID uuid) {
try{
BluetoothServerSocket clientSocket = device.createRfcommSocketToServiceRecord(uuid);
//clientSocket without method and invoke is not working either
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
clientSocket = (BluetoothSocket) m.invoke(device, 1);
//Here is where I get the error:
//io to Server Socket JSR82 Connection is not created, failed or aborted
clientSocket.connect();
// Start listening for messages.
StringBuilder incoming = new StringBuilder();
listenForMessages(clientSocket, incoming);
// Add a reference to the socket used to send messages.
transferSocket = clientSocket;
} catch (IOException ioe) {
this.printToast("Excep io toServerSocket:" + ioe.getMessage());
} catch (Exception e) {
this.printToast("Excep toServerSocket:" + e.getMessage());
}
}
On serverSocket.accept() or clientSocket.connect() I get the exception:
Connection is not created, failed or aborted
I would appreciate if anyone could guide me towards getting the data reading part working. Thanks.
Take a look at Android's BluetoothChat example included with the Android SDK. I think it does exactly what you want.
$ANDROID_SDK/samples/android-19/legacy/BluetoothChat/src/com/example/android/BluetoothChat
Read the managing the connection part.
Its clearly written in the documentation how to exchange (read/write) info between devices through Bluetooth. http://developer.android.com/guide/topics/connectivity/bluetooth.html

Handling a Biometric Fingerprint Attendance Device by using socket

I am trying to connect with a Biometric Fingerprint Attendance Device using a Java program. The device I am using is a Biocom Fingerprint attendance system. However, I am search and reading about that and I see the SDK could used which based on device type (which hard, not logical, moreover, it is not global solution!)
I research for a global standard on how to connect, send and retrieve data with a Fingerprint Device which again I wasn't lucky enough to find a clear solution. Currently, I tried to connect with the device by creating a Socket object (through Ethernet port) but also not executed with me. This open infinite loop problems on my head.
Is there any general, standard way to connect, send and retrieve data from such device using Java?
Can a Socket be considered as a solution for such problem?
If yes, what is wrong in my code below? What additional things more than the host IP and port number are needed to connect with the device?
The Socket code that used:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Requester {
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Requester() {
}
void run() throws IOException {
try {
// 1. creating a socket to connect to the server
requestSocket = new Socket("192.168.0.19", 4370);
System.out.println("Connected to given host in port 4370");
// 2. get Input and Output streams
in = new ObjectInputStream(requestSocket.getInputStream());
// 3: Communicating with the server
String line;
while (true) {
line = in.readLine();
if (line != null) {
System.out.println(line);
}
}
} catch (UnknownHostException unknownHost) {
System.err.println("You are trying to connect to an unknown host!");
} catch (IOException ioException) {
ioException.printStackTrace();
} catch (Exception Exception) {
Exception.printStackTrace();
} finally {
in.close();
requestSocket.close();
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
System.out.println("client: " + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) throws IOException {
Requester client = new Requester();
client.run();
}
}
This image may give more details:
You don't need the ObjectInputStream. Just use the InputStream you get from requestSocket.getInputStream().
Alternatively use a terminal programm like putty to connect to your device. This requires no coding.
Biocom Biometrics are ZKTeco devices. ZkTeco devices are launched only with windows SDK. You can download the SDK from https://www.zkteco.com/en/download_catgory.html and use the DLL in java which can run only on Windows platorm. For HTTP communication, to work in any platform through any language, refer http://camsunit.com/application/zk-teco-essl-api-integration.html

Create listener for server socket response?

I have a server-client pair and I want to create a listener on the client end for new server responses. I am not sure how to do this, right now I can only interact in a direct synchronous way.
Here is the server:
public class TestServer {
public static void main(String[] args) throws Exception {
TestServer myServer = new TestServer();
myServer.run();
}
private void run() throws Exception {
ServerSocket mySS = new ServerSocket(4443);
while(true) {
Socket SS_accept = mySS.accept();
BufferedReader myBR = new BufferedReader(new InputStreamReader(SS_accept.getInputStream()));
String temp = myBR.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream serverPS = new PrintStream(SS_accept.getOutputStream());
serverPS.println("Response received: " + temp);
}
}
}
}
As you can see, it sends a response when it gets one. However in general I won't be sure when other servers I use send responses, so I would like to create an asynchronous listener (or at least poll the server for a response every half-second or so).
Here is what I'm trying on the client end:
protected static String getServerResponse() throws IOException {
String temp;
try {
BufferedReader clientBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
temp = clientBR.readLine();
} catch (Exception e) {
temp = e.toString();
}
return temp;
}
And just for reference, yes, sending over data from client to server works fine (it System.out's the data correctly). However, when I call the above function to try and retrieve the server response, it just hangs my application, which is an Android application in case that's relevant.
What I want from a function is just the ability to ask the server if it has data for me and get it, and if not, then don't crash my damn app.
On the client side create a ConnectionManager class which will handle all the socket I/O. The ConnectionManager's connect() method will create and start a new thread which will listen for server responses. As soon as it will receive a response it will notify all the ConnectionManager's registered listeners. So in order to receive asynchronously the server responses you will have to register a listener in ConnectionManager using its register(SomeListener) method.
Also, you can have a look at JBoss Netty which is an asynchronous event-driven network application framework. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

Categories

Resources