Java socket hanging when inside of java servlet - java

So I've been trying to figure out how to send messages between my arduino and my java servlet (tomcat) and have been bumping into some problems. I'm using this code in my java servlet:
ServerSocket server;
//socket server port on which it will listen
int port = 9876;
String message = "";
//create the socket server object
server = new ServerSocket(port);
System.out.println("Server socket created");
//keep listens indefinitely until receives 'exit' call or program terminates
while(true){
System.out.println("Waiting for client request...");
//creating socket and waiting for client connection
Socket socket = server.accept();
BufferedReader buff = new BufferedReader(new InputStreamReader (socket.getInputStream()));
System.out.println("Input stream established");
message = buff.readLine();
System.out.println("Message Received: " + message);
buff.close();
socket.close();
//terminate the server if client sends exit request
if(message.equalsIgnoreCase("exit")) break;
}
System.out.println("Shutting down Socket server!!");
//close the ServerSocket object
server.close();
But it's hanging on the
Socket socket = server.accept();
line. I assume this is because the messages i'm sending from the arduino aren't arriving. On the arduino side of things, this is my client:
if (client.connect(ip, 9876)) {
Serial.println("connected");
client.println("12345678");
Serial.println("Message sent");
} else {
Serial.println("connection failed");
}
Not much to it. Now, I've tried sending this as a HTTP POST request, but without success (surely i'm doing it incorrectly, i just don't know how to do it, i've tried for a while). I know this is probably horrifically written, but i'm very open to learning from you guys today.
The weird thing is that this works exactly how i want it to when i put the java server code in a new regular java project. Can anyone help me figure this out? Why is it hanging in the servlet but not in a regular java project?

Related

Storing and retrieving data from server host using Java

I have an assignment where I have to build a Client-Server communication using Java. So what I did was building a Client-Server connect using Sockets, the following way:
//Client code
Socket socket = new Socket("127.0.0.1", 4999);
//Server code
ServerSocket ss = new ServerSocket(4999);
Socket socket = ss.accept();
System.out.println("Client is connected");
For now, the communication between the client and the server is successful, I am able to send messages from client to server and vice versa. but the main problem is storing data on the server host, we were asked to store relevant data on the server host so the server could send it to the client.
Can someone please explain to me how to store data on the server and how to retrieve it ??
Thanks
To read from the server socket:
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//Do whatever you want with the DataInputStream
Source: https://www.baeldung.com/java-inputstream-server-socket
Then we can move to the input stream processing, here is a sample:
...
int i;
char c;
...
try{
// reads till the end of the stream
while((i = in .read())!=-1) {
// converts integer to character
c = (char)i;
// prints character
System.out.print(c);
}
} catch(Exception e){
//Handle....
} finally {
// Close stream...
}
Source: https://www.tutorialspoint.com/java/io/inputstream_read.htm#:~:text=io.-,InputStream.,the%20returned%20value%20is%20%2D1.
For writing to the socket (the response to the client), just follow the following tutorial, no need to repeat it here:
http://www.avajava.com/tutorials/lessons/how-do-i-write-a-server-socket-that-can-handle-input-and-output.html
I hope it helps

How would i change this code to allow more than one user input message to be sent between the client and server

I've just started with both java and networking with servers and clients. Although i understand the basics of whats going on, i was struggling to put it all together and do what i wanted to do in the title.
I was able to make this to send a message to the server, however i was wondering how i'd turn the message into a input string from the user, and also how id send multiple messages between the client and server
thanks
SERVER
import java.io.*;
import java.net.*;
public class Server {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
//Remember to close the socket once we have finished with it.
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
CLIENT
import java.io.*;
import java.net.*;
public class Client {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
//ServerIP:- IP address of the server.
String serverIP = "localhost";
try{
//Create a new socket for communication
Socket soc = new Socket(serverIP,portNumber);
//Create the outputstream to send data through
DataOutputStream dataOut = new DataOutputStream(soc.getOutputStream());
//Write message to output stream and send through socket
dataOut.writeUTF("Hello other world!");
dataOut.flush();
//close the data stream and socket
dataOut.close();
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
There are some "problems" with your code.
You should only close the ServerSocket if you are done.
You should handle the newly connected client inside a thread to allow multiple clients to simultaniously "send messages".
1.
you could easily wrap your code inside an while loop.
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
//Remember to close the socket once we have finished with it.
soc.close();
}
Now your programm should continue to accept clients. But only one at a time. You can now terminate the Server by stopping the programm or by changing the someCondition to false and accepting the next client.
A bit more advanced would be, to shutdown the ServerSocket to stop the programm and catching the exception inside the while loop.
2.
To allow multiple clients to be handled simultaniously, you should pack the handle part into another Thread.
private ExecutorService threadPool = Executors.newCachedThreadPool();
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console in a new Thread.
threadPool.submit(() -> {
DataInputStream dataIn = new
DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
}
//Remember to close the socket once we have finished with it.
soc.close();
}
The part inside the threadPool.submit block could be specified as an custom instance of the Runnable interface of as an method, to call it using method reference.
I assumed you are knowing about ThreadPools. They have multiple advantages over Threads
This should get you going for any number of clients.
Note: This is not good designed, but it is for demonstrational porpurses only.

Why TCP/IP server with listening port in java not working

I have written a code in java to interface my computer with a transmitter a transmitter device, with a communication board already implemented and ready to connect via TCP/IP to any server with a specific address IP (say 192.168.2.2) and listening to a specific port number (say 4000).
I followed the exact strep how to create a server side application in Java offering a that listening port, so that I can connect to that transmitter.
I don't understand why when I try to debug the code, it blocks a the line clientSocket = serverSocket.accept(), and throws a timeout exception.
Could someone help me find out where the error might be in my code?
Any help would be greatly appreciated.
Thanks.
Here is the code:
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Declares server and client socket, as well as the input and the output stream
ServerSocket serverSocket = null;
Socket clientSocket = null;
PrintWriter out;
//BufferedReader in;
BufferedReader in;
try{
InetAddress addr = InetAddress.getByName("192.168.2.2");
//Opens a server socket on port 4000
serverSocket = new ServerSocket(4000) ;
//Sets the timeout
serverSocket.setSoTimeout(30000);
System.out.println("Server has connected");
//Create a connection to server
System.out.println("Server listening connection from client ....");
//Listens and waits for client's connection to the server
clientSocket = serverSocket.accept();
// Creates input and output streams to socket
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//Reads response from socket
while((in.readLine())!= null ){
System.out.println ( in.readLine() );
}
System.out.println ( "Closing connection ....");
//Terminates connection
clientSocket.close();
serverSocket.close();
System.out.println("Connecton successfully closed");
}
catch(IOException e){
System.out.println(e);
}
}
}
Could someone help me find out where the error might be in my code?
There is no error in your code that could cause this problem. Clearly you haven't configured the device to connect to this server correctly, or the device isn't running, or it isn't connecting, or there is a firewall in the way. Investigate that.
However:
InetAddress addr = InetAddress.getByName("192.168.2.2");
What is this for? It isn't used.
System.out.println("Server has connected");
This is simply not true. The server hasn't connected. At this point all it has done is create a listening socket.
while((in.readLine())!= null ){
Here you are reading a line and throwing it away.
System.out.println ( in.readLine() );
Here you are printing every second line, having thrown every odd line away. The correct way to write this loop is:
String line;
while ((line = in.readLine()) != null)
{
System.out.println(line);
}
Note also that this server will service exactly one client and then exit. There should be a loop around everything from accept() to clientSocket.close(), and if there are multiple devices it should start a new thread per accepted socket to handle the I/O.
You specified timeout of 30 seconds, didn't you? :
serverSocket.setSoTimeout(30000);
So after 30 seconds, no matter whether stopped in debugger or running, this will timeout and throw exception.

TCP. client connects even if server doesn't accept him

I have TCP server-client application. It works but sometime something happens. Client connects to server but server says he doesn't accepted him.
Server side code:
while(!stopped){
try {
AcceptClient();
} catch(SocketTimeoutException ex){
continue;
} catch (IOException ex) {
System.err.println("AppServer: Client cannot be accepted.\n"+ex.getMessage()+"\n");
break;
}
...
private void AcceptClient() throws IOException {
clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(200);
out = new ObjectOutputStream(clientSocket.getOutputStream());
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Accepted connection from "+clientSocket.getInetAddress());
}
Client side code:
try {
socket = new Socket(IPAddress, serverPort);
socket.setSoTimeout(5000);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException e1) {
sendSystemMessage("DISCONNECTED");
sendSystemMessage(e1.getMessage());
return;
}
sendSystemMessage("CONNECTED");
If client connects the message:
Accepted connection from ... appears. But sometimes it doesn't appear
even if client sends message "CONNECTED"
Server is still runing the loop trying to get client and it is catching socketTimeoutException. Client is connected, sends message and waits for response.
I suspect a missing 'flush' inside your client's 'sendSystemMessage()'.
Unfortunately the constructor of ObjectInputStream attempts to read a header from the underlying stream (which is not very intuitive IMHO). So if the client fails to flush the data - the server may remain stuck on the line "in = new ObjectInputStream(socket.getInputStream())"...
As a side note it's usually better for a server to launch a thread per incoming client, but that's just a side remark (plus it obviously depends on requirements).
I found the problem. The communication on my net is too slow so it timeouts in getting inputstream. The solution has two parts. Flushing outputstream before getting inputstream. And set socket timout after streams are initialized.
serverside:
clientSocket = serverSocket.accept();
out = new ObjectOutputStream(clientSocket.getOutputStream());
out.flush()
in = new ObjectInputStream(clientSocket.getInputStream());
clientSocket.setSoTimeout(200);

Java Communication Server Client with Socket

i'm having trouble with my client/server program in java . I'm able to communicate from my client to my server but when i'm broadcasting from the server to the client it's not working.
There is the part of my program that is not working :
Server :
while (true) {
Socket socket = server.accept();
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write("Welcome to the server !");
out.flush();
}
Client ( running as a thread):
while(true){
try {
//s is the socket I get from the connection to the server
in = new BufferedReader (new InputStreamReader (s.getInputStream()));
String msg = in.readLine();
System.out.println(msg);
} catch (IOException ex) {
}
}
When I use my client programm I don't receive the message sent by the server . However when i use netcat on my terminal to establish the connection on the server, I got the message . I don't get it. Thanks
The client expects a complete line to be sent:
String msg = in.readLine();
It can only be sure the line is complete if it finds a line terminator character, or if the stream is closed. But the server doesn't send any EOL character, and doesn't close the stream either. So the client keeps waiting for the line to complete.

Categories