While loop in client-server program - java

so i was i have to do some simple client-server program.
Server side
`
public static void main(String[] args) throws IOException
{
ServerSocket ss = null;
try{ss= new ServerSocket(119);}
catch(IOException ioe){System.out.println("Can't connect to port.");}
Socket sock = null;
try{sock = ss.accept();}
catch(IOException ioe){System.out.println("Can't connect to client.");}
System.out.println("Connection successful.");
PrintStream out = null;
Scanner in = null;
try{
out = new PrintStream(sock.getOutputStream());
in = new Scanner(sock.getInputStream());
}catch(Exception e)
{
System.out.println("Error.");
}
String line;
String lines = "";
while((line = in.nextLine()) != null)
{
switch(line)
{
case "list":out.println("Printing something");break;
case "loop":
{
FileReader fr = new FileReader("D:\\Eclipse\\TestFiles\\text2.txt");
BufferedReader br = new BufferedReader(fr);
while((lines = br.readLine()) != null)
{
out.println(lines);
}
break;
}
default:
{
if(!(line.equals("end"))) out.println("Unknown command.Try again.");break;
}
}
out.flush();
if(line.equals("end"))
{
out.println("Connection over.");
break;
}
}
try{
in.close();
out.close();
sock.close();
ss.close();
}catch(IOException ioe){}
}
`
Client side
public static void main(String[] args)
{
Socket sock = null;
PrintStream out = null;
Scanner in = null;
Scanner sIn = null;
try{
sock = new Socket("localhost",119);
out = new PrintStream(sock.getOutputStream());
in = new Scanner(sock.getInputStream());
sIn = new Scanner(System.in);
}catch(Exception e){
System.out.println("Error connecting to server.");
System.exit(1);
}
System.out.println("Connection successful.");
String temp = "";
while((temp = sIn.nextLine()) != null)
{
out.println(temp);
while(in.hasNextLine())System.out.println(in.nextLine());
out.flush();
if(temp.equals("end")) break;
}
try{
sock.close();
in.close();
out.close();
}catch(IOException ioe){}
}
My problem is that on the client side when the second while loop(the on inside the first while loop) has to end, it does not and i am just entering commands in the client without any response

Fixes
Use PrintWriter for to write to the socket and BufferedReader to read from the socket. Open the PrintWriter in auto flush mode true in the below statement signifies that. This way you don't have to worry about flushing the stream.
PrintWriter out = new PrintWriter(sock.getOutputStream(),true);
Your closing statements are within loop, which closes streams and you cannot use them for the next iteration because you will get an exception. Pull them out of the while loop.
Unnecessary braces to delimit cases in the switch.
Your connection termination statements should be out of the switch case. Only then break will have a effect on the loop instead on the switch.
I used br.ready() to sense if the stream is ready to be read and then iterating through the loop. This is effective than your version.
while((temp = sIn.nextLine()) != null)
{
out.println(temp);
Thread.currentThread().sleep(1000);
while(in.ready())System.out.println(in.readLine());
out.flush();
if(temp.equals("end")) break;
}
Thread.currentThread().sleep(1000), is to get handle of the main thread and sleep it for 1000ms, this way I am letting br be ready with the server response. otherwise br.ready() will be false, for the present request, and it gets ready in the next iteration. I think you know what I trying to convey.
I did not check the case loop;
Server
import java.net.*;
import java.io.*;
import java.util.*;
public class chatServer
{
public static void main(String[] args) throws IOException
{
ServerSocket ss = null;
try
{
ss= new ServerSocket(8000);
}
catch(IOException ioe){System.out.println("Can't connect to port.");}
Socket sock = null;
try{sock = ss.accept();}
catch(IOException ioe){System.out.println("Can't connect to client.");}
System.out.println("Connection successful.");
PrintWriter out = null;
Scanner in = null;
try{
out = new PrintWriter(sock.getOutputStream(),true);
in = new Scanner(sock.getInputStream());
}catch(Exception e)
{
System.out.println("Error.");
}
String line;
String lines = "";
while((line = in.nextLine()) != null)
{
switch(line)
{
case "list":
out.println("1. bla | 2. ble | 3. bli");break;
case "group":out.println("Here group will be chosen.");break;
case "header":out.println("Returns header.");break;
case "loop":
FileReader fr = new FileReader("D:\\Eclipse\\TestFiles\\text2.txt");
BufferedReader br = new BufferedReader(fr);
while((lines = br.readLine()) != null)
{
out.println(lines);
}
break;
default:
if(!(line.equals("end")))
{
out.println("Unknown command.Try again.");
break;
}
}
if(line.equals("end"))
{
out.println("Connection over.");
break;
}
}
try{
in.close();
out.close();
sock.close();
ss.close();
}catch(IOException ioe){}
}
}
Client
import java.net.*;
import java.io.*;
import java.util.*;
public class chatClient
{
public static void main(String[] args) throws IOException, InterruptedException
{
Socket sock = null;
PrintStream out = null;
BufferedReader in = null;
Scanner sIn = null;
try
{
sock = new Socket("localhost",8000);
out = new PrintStream(sock.getOutputStream());
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
sIn = new Scanner(System.in);
}
catch(Exception e)
{
System.out.println("Error connecting to server.");
System.exit(1);
}
System.out.println("Connection successful.");
String temp = "";
while((temp = sIn.nextLine()) != null)
{
out.println(temp);
Thread.currentThread().sleep(1000);
while(in.ready())System.out.println(in.readLine());
out.flush();
if(temp.equals("end")) break;
}
try
{
sock.close();
in.close();
out.close();
}
catch(IOException ioe){}
}
}

Related

Multithreading with client server program

I am trying to implement multi threading with a client/server program I have been working on. I need to allow multiple clients to connect to the server at the same time. I currently have 4 classes: a Client, a Server, a Protocol and a Worker to handle the threads. The following code is what I have for those classes:
SocketServer Class:
public class SocketServer {
public static void main(String[] args) throws IOException {
int portNumber = 9987;
try (
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
Thread thread = new Thread(new ClientWorker(clientSocket));
thread.start(); //start thread
String inputLine, outputLine;
// Initiate conversation with client
Protocol prot = new Protocol();
outputLine = prot.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = prot.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("quit"))
break;
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
SocketClient Class:
public class SocketClient {
public static void main(String[] args) throws IOException
{
String hostName = "localhost";
int portNumber = 9987;
try (
Socket socket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("quit"))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} 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);
}
}
}
Protocol Class:
public class Protocol {
private static final int waiting = 0;
private static final int sentPrompt = 1;
private int status = waiting;
public String processInput(String theInput) {
String theOutput = null;
if (status == waiting) {
theOutput = "Please enter what you would like to retrieve: 'customer' or 'product' ";
status = sentPrompt;
}
else if ( status == sentPrompt ) {
if ( theInput.equalsIgnoreCase("product")) {
File f = new File("product.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current product entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("customer")) {
File f = new File("customer.txt");
Scanner sc = null;
try {
sc = new Scanner(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(Protocol.class.getName()).log(Level.SEVERE, null, ex);
}
while ( sc.hasNextLine() ) {
String line = sc.nextLine();
theOutput = "The current customer entries are : " + line;
}
return theOutput;
}
else if ( theInput.equalsIgnoreCase("quit")) {
return "quit";
}
else {
return "quit";
}
}
return theOutput;
}
}
The ClientWorker Class:
public class ClientWorker implements Runnable {
private final Socket client;
public ClientWorker( Socket client ) {
this.client = client;
}
#Override
public void run() {
String line;
BufferedReader in = null;
PrintWriter out = null;
try {
System.out.println("Thread started with name:"+Thread.currentThread().getName());
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while (true) {
try {
System.out.println("Thread running with name:"+Thread.currentThread().getName());
line = in.readLine();
//Send data back to client
out.println(line);
//Append data to text area
} catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
}
}
When I run the server and client, everything works fine as expected. Then when I try to run another client, it just hangs there and does not prompt the client to give a response. Any insight into what I am missing is greatly appreciated!
Your server code should address implement below functionalities.
Keep accepting socket from ServerSocket in a while loop
Create new thread after accept() call by passing client socket i.e Socket
Do IO processing in client socket thread e.g ClientWorker in your case.
Have a look at this article
Your code should be
ServerSocket serverSocket = new ServerSocket(portNumber);
while(true){
try{
Socket clientSocket = serverSocket.accept();
Thread thread = new ClientWorker(clientSocket);
thread.start(); //start thread
}catch(Exception err){
err.printStackTrace();
}
}
How many times does serverSocket.accept() get called?
Once.
That's how many clients it will handle.
Subsequent clients trying to contact will not have anybody listening to receive them.
To handle more clients, you need to call serverSocket.accept() in a loop.

Java socket is not recieving a response from the Print Writer

Server starts here:
public static void main(String[] args){
System.out.println("Server has started");
try {
ServerSocket socket = new ServerSocket(17000);
while(true){
ThreadedClass w;
w = new ThreadedClass(socket.accept());
Thread t = new Thread(w);
t.start();
}
} catch (IOException e) {
System.out.print("Failed");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Then this class:
package com.sandislandsrv.rourke750;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ThreadedClass implements Runnable{
private Socket socket;
public ThreadedClass(Socket socket){
this.socket = socket;
}
#Override
public void run() {
MysqlDataClass db = Start.getData();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
String cred = in.readLine();
String[] creds = cred.split(" ");
System.out.print(creds[0] + creds[1]);
boolean authenticate = db.getUsernamePassValid(creds[0], creds[1]);
if (!authenticate){
System.out.println("Failed to log in, bad password");
out.println("BAD");
out.close();
return;
}
out.println("GOOD");
String line;
while ((line = in.readLine()) != null){
if (line.equals("END")){
out.close();
return;
}
if (line.equals("GET")){
out.println(db.getMessages(creds[0]));
}
if (line.equals("IN")) break;
if (line.equals("REMOVE")){
line = in.readLine();
db.removeMessage(creds[0], line);
}
}
line = in.readLine();
String[] format = line.split("Theamjgfdngkngfd8998906504906595665");
String[] timeformat = format[1].split(":");
long time = System.currentTimeMillis()/1000;
if (Long.parseLong(timeformat[0]) != 0)
time += 3600 * Long.parseLong(timeformat[0]);
if (Long.parseLong(timeformat[1]) != 0)
time += 60 * Long.parseLong(timeformat[1]);
if (Long.parseLong(timeformat[2]) != 0)
time += Long.parseLong(timeformat[2]);
db.addMessage(creds[0], format[0], time);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void remove(){
}
}
Then later on I call this method
public String[] getNames(){
StringBuilder builder = new StringBuilder();
try {
Socket socket = new Socket("share.betterassociations.com", 17000);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println(username.getText().toString() + " " + password.getText().toString());
System.out.print("test");
String passed = input.readLine();
System.out.print("test2");
if (passed.equals("BAD")) {
System.out.print("fail");
loginerror.setVisible(true);
socket.close();
return null;
}
System.out.print("test2");
out.println("GET");
String line;
while ((line = input.readLine()) != null){
if (line.equals("END")) break;
builder.append(line);
}
out.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return builder.toString().split(" ");
}
For some reason it seems to get frozen in the last method posted with the String passed = input.readLine();
I don't understand why its happening because I am sending a string to the client from the server but the client isn't receiving it.
Add a call to out.flush() after you write to it for both server and clients' outputStreams, like here
....
out.println("GOOD");
out.flush();
....
Alternatively, enable autoflushing by changing your server (the client is already enabled) here:
....
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
....
But per the documentation:
if automatic flushing is enabled it will be done only when one of the println, printf, or format methods is invoked, rather than whenever a newline character happens to be output.
So don't get gotchya'ed

Java Sockets - A Client that reads the data the server gets

I am working on a java socket program and have difulcites with the client part. The server get's what all the clients write, but the client only gets what it writes. Could someone provide me with an example of a client part of a program that gets what all the clients write? Thanks!
Here is an "echo server" example
import java.io.*;
import java.net.*;
class TCPServer
{
public static void main(String argv[]) throws IOException
{
ServerSocket serverSocket = null;
DataInputStream serverInput = null;
PrintStream serverOutput = null;
String line = null;
Socket clientSocket = null;
// create server socket
try
{
serverSocket = new ServerSocket(2012);
clientSocket = serverSocket.accept();
serverInput = new DataInputStream(clientSocket.getInputStream());
serverOutput = new PrintStream(clientSocket.getOutputStream());
}
catch(IOException e){System.out.println(e);}
// receive data and send it back to the client
try
{
while(true)
{
line = serverInput.readLine();
if(line.equals("exit"))
{
break;
}
else
{
if(!line.equals(null) && !line.equals("exit"))
{
System.out.println("Received " +line);
line = line+" MODIFIED";
serverOutput.println(line);
}
}
}
}
catch(IOException e){System.out.println("SERVER SIDE: Unable send/receive data");}
try
{
serverInput.close();
serverOutput.close();
clientSocket.close();
serverSocket.close();
}
catch(IOException e){System.out.println(e);}
}
}
Here is the client
import java.io.*;
import java.net.*;
public class TCPClient
{
public static void main(String[] args) throws IOException
{
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("localhost", 2012);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
if(userInput.equals("exit"))
break;
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}

Console based login application using java sockets

I am making a console based java application - which will check the username and password of client. What I want is the data entered by client must enter to server in a line by line format i.e pressing enter must send username data and password for next enter press. But what the problem is - until I quit at the client side the data is not sent to the server. Meaning , when client hits 'Bye.' then the client is closed and server receives the data then. Help me in this regard as this is the first step - later I have to check database with this username and password on server. My codes are as follows :
Server :
import java.net.*;
import java.io.*;
public class EchoServer2 extends Thread
{
protected Socket clientSocket;
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(2010);
System.out.println ("Connection Socket Created");
try {
while (true)
{
System.out.println ("Waiting for Connection");
new EchoServer2 (serverSocket.accept());
}
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
}
catch (IOException e)
{
System.err.println("Could not listen on port.");
System.exit(1);
}
finally
{
try {
serverSocket.close();
}
catch (IOException e)
{
System.err.println("Could not close port.");
System.exit(1);
}
}
}
private EchoServer2 (Socket clientSoc)
{
clientSocket = clientSoc;
start();
}
public void run()
{
System.out.println ("New Communication Thread Started");
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
true);
PrintWriter out1 = new PrintWriter(clientSocket.getOutputStream(),
true);
BufferedReader in = new BufferedReader(
new InputStreamReader( clientSocket.getInputStream()));
BufferedReader in1 = new BufferedReader(
new InputStreamReader( clientSocket.getInputStream()));
String inputLine,u,p;
while ((u = in.readLine()) != null && (p = in.readLine()) != null)
{
System.out.println ("U: " + u);
out1.println(u);
System.out.println ("P: " + p);
out1.println(p);
if (u.equals("Bye."))
break;
}
out1.close();
out.close();
//in1.close();
in.close();
clientSocket.close();
}
catch (IOException e)
{
System.err.println("Problem with Communication Server");
System.exit(1);
}
}
}
Client :
import java.io.*;
import java.net.*;
import java.lang.*;
import java.io.Console;
public class EchoClient2 {
public static void main(String[] args) throws IOException {
String serverHostname = new String ("127.0.0.1");
if (args.length > 0)
serverHostname = args[0];
System.out.println ("Attemping to connect to host " +
serverHostname + " on port .");
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader in1 = null;
try {
echoSocket = new Socket(serverHostname, 2010);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: " + serverHostname);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader std = new BufferedReader(
new InputStreamReader(System.in));
String upwd,uname,text;
Console console = System.console();
String username = console.readLine("Username:");
char[] pwd = console.readPassword("Password:");
upwd=new String(pwd);
while (username!=null && upwd!=null && (uname = stdIn.readLine()) != null)
{
out.println("Username:"+username);
out.println("Password:"+upwd);
// end loop
if (uname.equals("Bye."))
break;
}
out.close();
stdIn.close();
echoSocket.close();
}
}
On the client side, do out.flush() after writing the password to the stream.

How can I transfer files from Server-Side to Client using Sockets?

I'm having trouble on where to begin performing this task, I'd like some examples or input on how I should set up my server/client components to receive and send data including letting the client download images.
Here's my client-side code:
package V3;
import java.io.*;
import java.net.*;
public class Version3Client {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("localhost", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
And here's my server-side code:
package V3;
import java.net.*;
import java.io.*;
public class Version3Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
while (listening)
new Version3ServerThread(serverSocket.accept()).start();
serverSocket.close();
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
Version3Protocol kkp = new Version3Protocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
Thread class added for further specification:
package V3;
import java.net.*;
import java.io.*;
import java.io.FileWriter;
public class Version3ServerThread extends Thread {
private Socket socket = null;
public Version3ServerThread(Socket socket) {
super("Version3ServerThread");
this.socket = socket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine, outputLine;
Version3Protocol kkp = new Version3Protocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
if(kkp.getInteraction()){
Logging.writeToFile(socket.getInetAddress());
}
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The code so far, the client-server-communication without the file-transfer ability, looks fine to me. I wanted to compile to find any errors but you didnt include Version3Protocol and Logging. If it does compile then your next step would be to open the file you want to transfer on the server with a FileInputStream and a new file for writing on the client with FileOutputStream:
http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileInputStream.html
http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileOutputStream.html
You can then read the file into buffer, transfer it using the socket, receive it on the client-side, and copy the buffer-contents into the FileOutputStream there.

Categories