TCP Server response timeout - java

I have been tasked with getting a simple TCP Client to timeout. The client works as expected, however I cannot seem to get the client to timeout when the client does not receive an input for 3 seconds or more.
I have a basic understanding of SO_TIMEOUT, but can't get it to work here.
Please help
Here is my code:
TCPClient
private static final String host = "localhost";
private static final int serverPort = 22003;
public static void main(String[] args) throws Exception
{
try
{
System.out.println("You are connected to the TCPCLient;" + "\n" + "Please enter a message:");
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
#SuppressWarnings("resource")
Socket client = new Socket(host, serverPort);
client.setSoTimeout(3000);
while(true)
{
DataOutputStream outToServer = new DataOutputStream(client.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
String input = inFromUser.readLine();
outToServer.writeBytes(input + "\n");
String modedInput = inFromServer.readLine();
System.out.println("You Sent: " + modedInput);
try
{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
System.out.println("Slept-in");
e.getStackTrace();
}
}
}
catch(SocketTimeoutException e)
{
System.out.println("Timed Out Waiting for a Response from the Server");
}
}

setSoTimeout doesn't do what you think it does. From the Javadoc:
With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this
amount of time.
It's a timeout for reads from the socket, so reads() will return after 3 seconds even if there's no data. It's not a timeout for socket inactivity - i.e. the socket won't disconnect after being idle for 3 seconds.

Related

Java TCP Client-Server - stuck in infinite loops in both applications [duplicate]

This question already has answers here:
Importance of the new line "\n" in Java networking
(2 answers)
Closed 4 years ago.
I have a Client and a Server, they should have a communication in both ways. Everything worked well, client sent some information to server, and server did something with that information. Now that I tried to implement server replying to. After I've tried implementing that, both programs are now stuck in an infinite loop, waiting for information from the other side.
Here is my code for the server side:
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
logger.log(Level.INFO, "args[0]: {0} args[1]: {1} args[2]: {2} args[3] {3}", new Object[]{args[0], args[1], args[2], args[3]});
pathToExcel = args[0];
pathToDatabase = args[1];
numberOfAccounts = Integer.parseInt(args[2]);
portNumber = Integer.parseInt(args[3]);
listIE = new ArrayList<>();
listIE = Loader.getList(numberOfAccounts, pathToExcel);
DBBroker.createTables(pathToDatabase);
System.out.println("Check value: " + DBBroker.checkDB());
if (DBBroker.checkDB() == false) {
DBBroker.insertData();
DBBroker.insertDataBalance();
} else {
System.out.println("Data has already been inserted into the database");
}
startServer();
}
public static void startServer() throws IOException {
//ServerSocket ss = new ServerSocket(portNumber);
ServerSocket ss = new ServerSocket(portNumber);
logger.log(Level.INFO, "Server started on port number: {0}", portNumber);
try {
while (true) {
Socket clientSocket = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream clientOutput = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Client connected ");
//***************************************************************************
String answer = input.readLine();
//***************************************************************************
System.out.println("prosao readline");
//logger.info("Client logged in on port " +portNumber);
String[] niz = answer.split("_");
//System.out.println("niz: " +Arrays.toString(niz));
serverPortNumber = Integer.parseInt(niz[0]);
accountName = niz[1];
receiverName = niz[2];
amount = Integer.parseInt(niz[3]);
//System.out.println("Server port number: " +serverPortNumber + " accountname: " +accountName +" receiver name: " +receiverName + " amount: " +amount);
parseRequestFromClient();
System.out.println("Prosao request");
clientOutput.writeBytes("Kraj");
clientSocket.close();
}
//ss.close();
} catch (Exception e) {
e.printStackTrace();
}
}
And here is my code for the client side:
public static void main(String[] args) throws IOException {
String messageFromServer = "";
logger.log(Level.INFO, "args[0]: {0} args[1]: {1} args[2]: {2} args[3] {3}", new Object[]{args[0], args[1], args[2], args[3]});
Socket socket = new Socket("localhost", Integer.parseInt(args[0]));
//logger.info("args[0]: " +args[0] +" args[1]: " +args[1] +" args[2]: " +args[2] +" args[3] " +args[3]);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String dataForServer = args[0]+"_"+args[1]+"_"+args[2]+"_"+args[3];
System.out.println("Data for server: " +dataForServer);
outputStream.writeBytes(dataForServer);
System.out.println("prosao dataforserver");
//***************************************************************************
String answer = input.readLine();
//***************************************************************************
System.out.println("prosao readline");
System.out.println(answer);
socket.close();
}
Server side gets stuck at the ss.accept() line, while the Client side gets stuck at input.readLine()
I didn't add the whole project because a large portion of it is not relevant to the problem and it has a lot of code.
Your server was blocking on readLine(). It blocks for a line terminator. The client was only sending a raw string. The solution is to send a line terminator with each raw string.
The same applies when the server responds to the client.
As Simon has pointed out a printwriter would be a good choice if your message protocol is to pass line terminated strings.

Sending file details over java socket fails

The code below is part of a larger attempt; it tries to transfer a file's details between server and client and fails miserably. Server writes 3 elements to socket, client should receive same 3 elements. Client blocks after reading first element. What am I doing wrong?!?
public class SocketIssues {
static void client() throws Exception {
new Thread() {
#Override
public void run() {
try {
Thread.sleep(1000); // enough time for server to open its socket
Socket s = new Socket("localhost", 50001);
final DataInputStream dis = new DataInputStream(s.getInputStream());
final BufferedReader in = new BufferedReader(new InputStreamReader(dis));
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + in.readLine());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
static void server() throws Exception {
ServerSocket ss = new ServerSocket(50001);
Socket s = ss.accept();
System.out.println("SERVER: client connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(dos));
long l = 2194;
String nume = "The file name";
out.write("FILE1" + System.lineSeparator());
out.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: done sending" + System.lineSeparator());
}
public static void main(String[] args) throws Exception {
client();
server();
}
}
Try sticking with just the DataOutputStream instead of mixing them up between data and a buffered writer and use the read/write UTF() method like you're already doing with the last object:
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
long l = 2194;
String nume = "The file name";
dos.writeUTF("FILE1");
dos.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: fisier trimis" + System.lineSeparator());
then in the client:
final DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + dis.readUTF());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
Essentially, there's 2 layers of buffering going on. It's possible that when you call readLine() from the BufferedReader, it goes ahead and steals more bytes from the underlying stream because, well, that's what it's supposed to do. Then, when you go back to the DataInputStream and try to read an object, the preamble is gone (BufferedReader stole it), and it'll block waiting for it, eventhough there's bytes in the stream.

Java Sockets - Server hangs after client sends its response

Just trying to get a handle on sockets. The server and client are running in two different programs.
They seem to be connecting fine to each other but the client will not properly send its output to the server. The server just hangs. Here's the code:
Server:
private ServerSocket serverSocket;
private Socket client;
public void run() throws Exception {
serverSocket = new ServerSocket(20005);
while(currentState == Game.State.NORMAL) {
client = serverSocket.accept();
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String clientInput = in.readLine();
// Takes the client input string and does some simple game logic that returns a Gson object
Gson serverResponse = processInput(clientInput);
out.write(serverResponse.toString());
out.flush();
}
}
Client:
Socket clientSocket;
void run() throws Exception {
clientSocket = new Socket("192.168.0.24", 20005);
PrintWriter out;
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Print the state of the game - returns false if state is win or lose.
while(printState()) {
out = new PrintWriter(clientSocket.getOutputStream(), true);
// This method just takes some input from the console
String clientInput = getInput();
out.write(clientInput);
out.flush();
String serverResponse = in.readLine();
updateState(serverResponse);
}
}
}
There is some underlying game logic that is happening but it's pretty minor and should be irrelevant. I imagine I am just misunderstanding something fundamental here.
Thanks all.
Make sure you send a newline character to match the in.readLine() statement in the Server.
out.write(clientInput + "\n");
The same applys when sending data from Server->Client.

Client doesn't receive output from server's DataOutputStream

I'm currently attempting to code my first client>server system to transmit packets containing strings back and forth through a network. However I'm having a problem in that the following is happening:
The client sends message to the server, the server receives the message, processes the message, and then supposedly sends a reply to the client, but the client never receives this message and hangs waiting for a response from the server. Here is the code:
SERVER:
public static void handlePackets() throws Exception {
String clientSentence;
String returnToClient;
ServerSocket welcomeSocket = new ServerSocket(1337);
System.out.println("Packet receiver initialized!");
while (run) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received Packet: " + clientSentence);
System.out.println("Compiling return to client.");
returnToClient = "";
if (clientSentence.startsWith("Handshake-")) {
returnToClient = handleHandShake(clientSentence);
}
outToClient.writeBytes(returnToClient);
System.out.println("Sent client response " + returnToClient);
}
welcomeSocket.close();
}
CLIENT:
public static String sendTCP(String host, String content) {
try {
System.out.println("Packet sender sending TCP packet " + content);
String serverResponse;
Socket clientSocket = new Socket(host, 1337);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(content + '\n');
System.out.println("Send data to sever. Awaiting response.");
serverResponse = inFromServer.readLine();
clientSocket.close();
System.out.println("Server response received " + serverResponse + " result was returned to caller.");
return serverResponse;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
The client is calling readLine() but the server isn't writing a line, just bytes, so the client is waiting forever for the line terminator. Append '\n' to the server's reply. Also the server should close the accepted socket once it's finished with it. Do this by closing whatever writer or output stream you have wrapped around it, not by closing the socket itself.
You should use BufferedOutputStream instead of DataOutputStream. It will work for simple data as is but you are liable to charset problems if you don't fix it sooner or later. In general you should always use symmetric input and output streams or readers.
1) You should close or flush outToServer / outToClient
2) When you read with BufferedReader you should write with BufferedWriter, not DataOutputStream

Client-Server-Client communication using Sockets

I am building a small chat application in which client A wants to send something to client C with server B in between. First of all is this a correct approach for the problem??. I am able to send and receive data to and from a server but it is limited to only the client.For example if Client A sends data to server B and client C is sending data to server B then i can send data back to A and C just like an echo server. But what i want is to forward data coming from Client A to Client C via server B.
The following is the server code:
public class Server {
public static void main(String[] args) {
int port = 666; //random port number
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting for a client....");
System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
System.out.println();
while(true) {
Socket socket = ss.accept();
SSocket sSocket = new SSocket(socket);
Thread t = new Thread(sSocket);
t.start();
System.out.println("Socket Stack Size-----"+socketMap.size());
}
}
catch (Exception e) { }
}
}
class SSocket implements Runnable {
private Socket socket;
public SSocket(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
}
catch (Exception e) { }
}
}
The client code is :
public class Client {
public static void main(String[] args) {
int serverPort = 666;
try {
InetAddress inetAdd = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inetAdd, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
System.out.println();
String line = null;
while (true) {
line = keyboard.readLine();
System.out.println("Wrinting Something on the server");
dOut.writeUTF(line);
dOut.flush();
line = dIn.readUTF();
System.out.println("Line Sent back by the server---" + line);
}
}
catch (Exception e) { }
}
}
When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.
now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:
after the accept:
clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);
Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.
Iterator<DataOutputStream> it = clients.iterator();
while ((message = reader.readLine()) != null) { //reading
while (it.hasNext()) {
try {
DataOutputStream oss = it.next();
oss.write(message);//writing
oss.flush();
}
catch (Exception e) { }
}
}
This will loop through all the available clients in the arraylist and will send to all. you can define ways to send to only some.
For example:
maintain a ActiveClients arraylist and with some GUI interaction may be or maybe, define what all clients you want to send the message.
Then add just those clients outputStreams to ActiveClients
ActiveClients.add(clients.get(2));
or remove them, if you don't want them.
ActiveClients.remove(clients.get(2));
and now just loop through this arraylist to send the data as above.
You can create message queue for each client:
Client A sends message 'Hi' with address Client C to server B.
Server B receives message and adds it to message queue of client C.
Thread in server B which communicates with client C check message queue, retrieve message and sends it to client C.
Client C receives message.
If I am not mistaken, you must be having a problem with receiving a message from the Server or SSocket class. What happens with your code is that when you send a message from the client to the server the Server class receives your messages also gives an echo of the message in the client. However, when you send a message from the Server class, you don't get any messages in the Client Class.
To get this to work, you would have to modify your code in the following fashion:
SSocket Class
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
You should add these lines:
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
Replace the while loop with this one and it will work fine.
while (true) {
line = dIn.readUTF(); //Takes the msg from the client
System.out.println("Recievd the line----" + line); //Prints the taken message
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
dOut.flush();
System.out.println("waiting for the next line....");
}

Categories

Resources