Not able to run multithreaded server program in Java - java

Here is the server code
package echoserver;
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) {
try {
//establish server socket
ServerSocket s = new ServerSocket(1981);
//Thread client connectionsincoming
while (true) {
//wait for incoming connection
Socket incoming = s.accept();
Runnable r = new ThreadedEchoHandler(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package echoserver;
import java.net.*;
import java.util.*;
import java.io.*;
class ThreadedEchoHandler implements Runnable {
public ThreadedEchoHandler(Socket i) {
//initializing socket
incoming = i;
}
public void run() {
try {
try {
//recieve input stream from socket
InputStream inStream = incoming.getInputStream();
//recieve output stream from socket
OutputStream outStream = incoming.getOutputStream();
//Create a scanner from input stream
Scanner scan = new Scanner(inStream);
//Create printer writer from output stream and enabled auto flushing
PrintWriter out = new PrintWriter(outStream, true);
//prompt users on how to exit program soon as a long in into the server
out.println("Enter BYE to exit");
boolean done = false;
//while done is not true and scanner has next line loop
while (!done && scan.hasNextLine()) {
//reading text that came in from the socket
String line = scan.nextLine();
//On the server print the ip address of where the text is coming from and the text they typed
System.out.println("Recieved from " + incoming.getInetAddress().getHostAddress() + ": " + line);
//Echo back the text the client typed to the client
out.println("Echo: " + line);
//if they type BYE in caps terminate there connection and I also trimmed whitespaces
if (line.trim().equals("BYE")) {
done = true;
}
}
} //finally close the socket connection
finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Socket incoming;
}
and here is the code for client
package client;
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws IOException {
PrintWriter out = null;
try {
Socket s = new Socket(InetAddress.getLocalHost(), 1981);
System.out.println("Connected to server on port 1981");
out = new PrintWriter(s.getOutputStream());
out.println("Hello");
s.close();
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
}
Socktes are getting created successfully but when control goes to t.start() method call it is not calling run() method of ThreadedEchoHandler class.
Why is this happening? any idea?

The client writes "Hello" to the PrintWriter. So far, so good.
You may expect that the PrintWriter sends this text directly to the socket, but it doesn't. The documentation from the PrintWriter(OutputStream) constructor says that it creates a PrintWriter without automatic line flushing. This means that you have to call out.flush() whenever you want something to be actually sent.
Until you call out.flush() the text only exists in some internal buffer, and the server will not be able to see it.

My guess would be that the acept statement is blocking forever because no client is connecting to the server. You could wrap accept() in prints to prove or disprove.

Related

How to retrieve data from a file very fast in Java

I have a situation like, I am provided with a log file that consists of Strings. What I have to do is , I need to retrieve each string from the file and pass through a Socket and when the End of the File reaches it has to go again to the beginning of the file and send again the Strings. I have written a simple code using an infinite thread that sends the strings and when the EOF comes I am closing the file and again re-opening the file using new BufferedReader object. And I am also giving a small amount of 5ms of thread sleep, but after some time my Process is entering into Pause state (Like a Dead Lock). Is there anyway to improve the speed of transfer? or else can I eliminate the Pause state.
Below is my Simple code:
public class Write extends Thread{
private static final String FileName = "Messages.txt";
private static final int port = 8080;
private final int time = 5;
ServerSocket serverSocket;
Socket writeSocket;
#Override
public void run()
{
try
{
serverSocket = new ServerSocket(port);
System.out.println("Server listening on port " + port+ " ...");
Socket writeSocket = serverSocket.accept();
System.out.println("Connected to Client : "+ writeSocket.getLocalSocketAddress());
OutputStream outStream = writeSocket.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true);
BufferedReader input = new BufferedReader(new FileReader(FileName));
String str = "";
while(true)
{
str = input.readLine();
if(str==null ){
input.close();
input = new BufferedReader(new FileReader(FileName));
}
else{
System.out.println("Outgoing Message>>"+str);
out.println(str);
Thread.sleep(time);
}
}
}
catch(IOException e) {System.out.println(e); } catch (InterruptedException ex) {
Logger.getLogger(Write.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Let me give you a simple explanation. Consider the above code is in a Server code. And when I run a client machine in the same PC, I can able to send the messages at some(high) speed but after sometime, both the client and the Server are entering into a Pause state. I feel this like a Dead Lock. The client is showing like the Server is disconnected and again Connected. When I close the Client then again Server is starting. Can anyone tell me is there a way to process the strings at a very high speed?
Re the program blocking, I would suggest:
put a System.out.print("A") before out.println() and a System.out.print("B") after. If it blocks with "A" as the last message in the output, then the problem is at the client side (they're not consuming the data, causing eventually the sender to block).
If the previous situation happens, write your own simple client which just reads data from the socket and throws it away, so you can demonstrate the problem is at the other side.
Re speed, you want to remove the sleep and System.out.println.
Why not use java nio to read all lines?
https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAllLines-java.nio.file.Path-java.nio.charset.Charset-
Or is the file too big to do this?
your code that reads the log file is just fine. no need to make it faster. see below (I commented the parts of the code that deal with the socket and the code works well at reading the log file multiple times. there is no sign of slowing down or deadlocks) :
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Write extends Thread {
private static final String FileName = "/tmp/Messages.txt";
private static final int port = 8080;
private final int time = 5;
ServerSocket serverSocket;
Socket writeSocket;
public static void main(String[] args) {
Write write = new Write();
Thread thread = new Thread(new Write());
thread.start();
}
#Override
public void run() {
try {
// serverSocket = new ServerSocket(port);
// System.out.println("Server listening on port " + port + " ...");
// Socket writeSocket = serverSocket.accept();
// System.out.println("Connected to Client : " + writeSocket.getLocalSocketAddress());
//
// OutputStream outStream = writeSocket.getOutputStream();
// PrintWriter out = new PrintWriter(outStream, true);
BufferedReader input = new BufferedReader(new FileReader(FileName));
String str = "";
while (true) {
str = input.readLine();
if (str == null) {
input.close();
input = new BufferedReader(new FileReader(FileName));
} else {
System.out.println("Outgoing Message>>" + str);
//out.println(str);
Thread.sleep(time);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (InterruptedException ex) {
Logger.getLogger(Write.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Simple Client Server Java Program not going into while loop

I had stumbled upon a dead block when doing my assignment. It's a simple server and client program.
The details of this program is as follows;
Create a server class EncryptServer that listens for incoming connections. If there is a connection, accept it and create a thread EncryptServerSession to handle the input and output stream.
Create a thread class EncryptServerSession that takes in the input and output stream from the server class and process it.
Create a client class EncryptClient that connects to the server class and takes output stream from EncryptServerSession through EncryptServer.
Somehow the while true loop of the EncryptClient class is not working. I cannot seem to get into the loop. Is something wrong with my code? Thanks in advance.
EncryptServer
import java.net.*;
import java.io.*;
public class EncryptServer
{
public EncryptServer() throws IOException
{
ServerSocket serverSocket = new ServerSocket(1122);
System.out.println("Server started.");
while (true)
{
Socket conSocket = serverSocket.accept();
System.out.println("Client connected from " +
conSocket.getLocalAddress().getHostName());
Thread session = new
EncryptServerSession(conSocket.getInputStream(),
conSocket.getOutputStream());
session.start();
}
}
public static void main(String[] args)
{
try
{
EncryptServer server = new EncryptServer();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
EncryptServerSession
import java.net.*;
import java.io.*;
public class EncryptServerSession extends Thread
{
BufferedReader in;
Writer out;
public EncryptServerSession(InputStream inStream, OutputStream outStream)
{
Reader read = new InputStreamReader(inStream);
in = new BufferedReader(read);
out = new OutputStreamWriter(outStream);
}
public void strEncrypt()
{
try
{
String message = in.readLine();
out.write(message);
out.flush();
}
catch (Exception e)
{
}
}
public void run()
{
try
{
//System.out.println(in.readLine());
out.write("Please enter the message to be encrypted: ");
out.flush();
//strEncrypt();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
EncryptClient
import java.net.*;
import java.io.*;
public class EncryptClient
{
BufferedReader input, userTerm;
Writer output;
String line;
public EncryptClient() throws IOException
{
Socket clientSocket = new Socket("localhost", 1122);
Reader read = new InputStreamReader(clientSocket.getInputStream());
input = new BufferedReader(read);
userTerm = new BufferedReader(new InputStreamReader(System.in));
output = new OutputStreamWriter(clientSocket.getOutputStream());
/////////////// Somehow I cannot get into this loop, why? //////////
while (true)
{
System.out.println("test ");
System.out.println(input.readLine());
System.out.println("Enter message to be encrypted: ");
output.write(userTerm.readLine());
output.flush();
}
/////////////// Somehow I cannot get into this loop, why? //////////
}
public static void main(String[] args)
{
try
{
EncryptClient client = new EncryptClient();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
As I understand, you are trying to send a message to a server, do some logic, then send it back to the client. The above code seems to run well on my side. Here's what I've done:
run EncryptServer first. I expect this is the issue you are facing. or maybe your firewall isn't letting you listen on sockets.
in EncryptServerSession, You are reading lines but you aren't writing lines. either close the stream or write a new line after you finish.
...
out.write(message);
out.write("\r\n"); // write new line
out.flush();
...
} finally {
try {
out.close();
} catch (IOException e) {
}
}
OR
...
out.write(message);
out.write("\r\n"); // write new line
out.flush();
...

Simple Networking; Threads issue

I'm trying to make a simple client-server networking program. Initially, I was not running the Server and Client objects concurrently. The command prompt would just get stuck on trying to run the program. I then decided to use threads. The result is the same; I believe I have to use wait() and notify() somewhere but I'm not able to get it.
The Server needs to run first, but it will have to wait for the incoming Socket reference before it can proceed. I believe some lines need to be shifted here and there before a wait-and-notify mechanism is implemented. Here's my code so far -:
package networking;
import java.net.*;
import java.io.*;
import java.util.Scanner;
class Server implements Runnable
{
ServerSocket ss;
Socket incoming;
public void run()
{
try
{
ss = new ServerSocket(8189);
incoming = ss.accept();
OutputStream outs = incoming.getOutputStream();
InputStream ins = incoming.getInputStream();
Scanner in = new Scanner(ins);
PrintWriter out = new PrintWriter(outs);
out.println("Hello, Bye to exit");
out.println("This is the server program");
out.println("It will echo client stuff");
boolean done = false;
while(!done && in.hasNextLine())
{
out.println("Echo: " + in.nextLine());
if(in.nextLine().trim().equals("Bye"))
done = true;
}
incoming.close();
}
catch(IOException e)
{
System.err.println(e.getMessage());
}
}
}
class Client implements Runnable
{
Socket s;
public void run()
{
try
{
s = new Socket("localhost", 8189);
InputStream ins = s.getInputStream();
OutputStream outs = s.getOutputStream();
Scanner in = new Scanner(ins);
PrintWriter out = new PrintWriter(outs);
while(in.hasNextLine())
System.out.println("Client: " + in.nextLine());
out.println("Bye");
s.close();
}
catch(IOException e)
{
System.err.println(e.getMessage());
}
}
}
public class Networking
{
public static void main(String... args)
{
Thread server = new Thread(new Server());
Thread client = new Thread(new Client());
server.start();
client.start();
}
}
Any tips and pointers would be much appreciated; I just need a nod(or more) in the right direction.
Your code for opening serve and client is correct. But the problem is in the while loop for reading or writing data it falls in a deadlock. Because after establishing the connection booth server and client is waiting for each other to write something in the stream. Try with this.
class Server implements Runnable {
ServerSocket ss;
Socket incoming;
public void run() {
try {
System.out.println("Server STarted");
ss = new ServerSocket(8189);
incoming = ss.accept();
System.out.println("Client accepted");
OutputStream outs = incoming.getOutputStream();
InputStream ins = incoming.getInputStream();
Scanner in = new Scanner(ins);
PrintWriter out = new PrintWriter(outs);
out.println("Hello, Bye to exit");
out.println("This is the server program");
out.println("It will echo client stuff");
boolean done = false;
while (!done) { // && in.hasNextLine()
// out.println("Echo: " + in.nextLine());
// if (in.nextLine().trim().equals("Bye")) {
// done = true;
// }
out.println("TEsting from server");
}
incoming.close();
System.out.println("End server");
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}

Client-Server connection

I have a java program that will connect the client to the server.
This includes making a file directory once the client had triggered the server through sending a message. For example: Once the server is running already, the client will then connect and will send a msg i.e "Your message: Lady", the server will receive a message like "Request to create a Directory named: Lady", after this a directory will be created named Lady.
But the problem is this connection is only for one-to-one. Like only one client can connect to the server...
This is the sample code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package today._;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
public class myServer {
protected static final int PORT_NUMBER = 55555;
public static void main(String args[]) {
try {
ServerSocket servsock = new ServerSocket(PORT_NUMBER);
System.out.println("Server running...");
while (true) {
Socket sock = servsock.accept();
System.out.println("Connection from: " + sock.getInetAddress());
Scanner in = new Scanner(sock.getInputStream());
PrintWriter out = new PrintWriter(sock.getOutputStream());
String request = "";
while (in.hasNext()) {
request = in.next();
System.out.println("Request to Create Directory named: " + request);
if(request.toUpperCase().equals("TIME")) {
try {
File file = new File("C:\\" + request);
if (!file.exists()) {
if (file.mkdir()) {
System.out.println("Directory is created!");
} else {
System.out.println("Failed to create directory!");
}
}
} catch (Exception e) {
System.out.println(e);
}
out.println(getTime());
out.flush();
} else {
out.println("Invalid Request...");
out.flush();
}
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
protected static String getTime() {
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
return (dateFormat.format(date));
}
}
package today._;
import java.io.*;
import java.net.*;
import java.util.*;
public class myClient {
protected static final String HOST = "localhost";
protected static final int PORT = 55555;
protected static Socket sock;
public static void main(String args[]) {
try {
sock = new Socket(HOST,PORT);
System.out.println("Connected to " + HOST + " on port " + PORT);
Scanner response = new Scanner(sock.getInputStream());
PrintWriter request = new PrintWriter(sock.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String txt = "";
while(!txt.toUpperCase().equals("EXIT")) {
System.out.print("Your message:");
txt = in.readLine();
request.println(txt);
request.flush();
System.out.println(response.next());
}
request.close();
response.close();
in.close();
sock.close();
} catch(IOException e) {
System.out.println(e.toString());
}
}
}
Multi-client servers are generally written one of two ways:
Create a thread for each client. To do this you would create a thread to handle the calls to accept() on the server socket and then spawn a new thread to handle calls on the Socket that it returns. If you do this, you need to make sure you isolate the code for each socket as much as possible. The accept thread will loop forever, or until a flag is set, and will just call accept, spawn a thread with the new socket, and go back to calling accept. All of the work is in the child thread.
Use NIO, or another technology, to multi-plex work into 1 more more threads. NIO uses a concept sometimes called select, where your code will be called when there is input available from a specific socket.
If you are just doing a small server, you can go with the simplest design and also won't have too many clients, so I would go with #1. If you are doing a big production server, I would look into a framework like netty or jetty that will help you do #2. NIO can be tricky.
In either case, be very careful with threads and the file system, you might not get the results you expect if you don't use a Lock from the concurrency package, or synchronize, or another locking scheme.
My final advice, be careful with having a client tell a server to do anything with the file system. Just saying, that is a dangerous thing to do ;-)
Your server class must use multiple threads to handle all connections:
class MyServer {
private ServerSocket servsock;
MyServer(){
servsock = new ServerSocket(PORT_NUMBER);
}
public void waitForConnection(){
while(true){
Socket socket = servsock.accept();
doService(socket);
}
}
private void doService(Socket socket){
Thread t = new Thread(new Runnable(){
public void run(){
while(!socket.isClosed()){
Scanner in = new Scanner(sock.getInputStream());
PrintWriter out = new PrintWriter(sock.getOutputStream());
String request = "";
// and write your code
}
}
});
t.start();
}
}

Why is this socket null?

I am creating a multi client chat server and i am pretty confident that it will work (Correct me if i'm wrong), I have the issue that on the socket that the client connects to is null so the connections can't be created because i use if(Socket != null) so i don't get errors but i will explain my layout real fast. The server starts with a starter class called (LaunchServer) that uses the class object ClientConnector as Minecraft and then starts the method runServer(). Here is the code for this class:
public class LaunchServer
{
public static void main(String[] args)
{
System.out.println("[Info] Running");
ClientConnector Minecraft = new ClientConnector();
Minecraft.runServer();
}
}
It's fairly simple. This brings us to the ClientConnector class. Here we start at the method runServer(). Right away we have a try catch block. in that block we print a message that the server is trying to connect to the port 1337. we then create a new ServerSocket called serversocket. We then send a message to the console saying that we have bound to port and that we are awaiting a connection. While true, we create a new Socket socket that equals ServerSocket.accept(); OMG fuck it. Heres the code. you know what it does...
import java.util.ArrayList;
import java.net.*;
import java.io.*;
public class ClientConnector
{
public static ArrayList<Socket> Connections = new ArrayList<Socket>();
public static void runServer()
{
try
{
System.out.println("[Info] Attempting to bind to port 1337.");
#SuppressWarnings("resource")
ServerSocket serversocket = new ServerSocket(1337);
System.out.println("[Info] Bound to port 1337.");
System.out.println("[Info] Waiting for client connections...");
while(true)
{
Socket socket = serversocket.accept();
new ClientHandler(socket).start();
Connections.add(socket);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
This takes us to the handler class:
import java.io.*;
import java.net.*;
public class ClientHandler extends Thread
{
Socket Socket;
public ClientHandler(Socket socket)
{
socket = Socket;
System.out.println("[Info] Client connected on port 1337.");
}
public void run()
{
while(true)
{
for(int i = 0; i < ClientConnector.Connections.size(); i++)
{
try
{
if(Socket != null)//This stays null...
{
ObjectOutputStream Output = new //These can't be created...
ObjectOutputStream(Socket.getOutputStream());
ObjectInputStream Input = new ObjectInputStream(Socket.getInputStream());
whileChatting(Input, Output);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public static void sendMessage(String message, String returnedMessage, ObjectOutputStream out)
{
try
{
if(!message.isEmpty())
{
out.writeObject("\247c[Server]\247d " + message);
out.flush();
System.out.println("[Chat] Sent: " + message);
}
else
{
out.writeObject(returnedMessage);
System.out.println("[Chat] Sent: " + returnedMessage);
}
out.flush();
System.out.println("[Info] Fluching remaining data to stream.");
System.out.println("\n[Server] " + message);
}
catch(IOException ioException)
{
System.out.println("[Warning] Error: ioException # sendMessage line 76.");
}
}
public static void whileChatting(ObjectInputStream input, ObjectOutputStream output) throws IOException
{
String message = "";
do
{
try
{
message = (String) input.readObject();
System.out.println("\n" + message);
sendMessage("", message, output);
}
catch(ClassNotFoundException classNotFoundException)
{
System.out.println("[Warning] Error: ClassNotFoundException # whileChatting line 1-7.");
System.out.println("\n idk wtf that user sent!");
}
}while(!message.equals("/stop"));
}
}
Read the run method. There you will see the null problem
Would the connection get accepted then passed to the hander class? How can a null connection get accepted? My question is how can i fix this problem?
The problem is you've got a logic error due to un-recommended naming conventions. You shouldn't name variables with keywords, like your Socket variable, and each variable should have a distinguishable name. e.g. not socket1, socket2 but serverSocket, clientSocket because that will make it easier for you and anyone else to read and fix your code.
Change
Socket Socket;
to
Socket connectedSocket;
and in your constructor
socket = Socket;
to
connectedSocket = socket;
then finally, in your run() method change
if(Socket != null)
to
if(connectedSocket != null)

Categories

Resources