I'm creating a server where clients connect to play a guessing game they are also to get points from doing this.
My only problem at the moment is that whenever my client guesses the number correctly it jumps to the server and says 'server null'. I want the guessing game to continue until the client inputs 'goodbye' - on which his/her score is given.
Here is my code could you point out where I've gone wrong and advise me on how I would achieve what I want. I think the problem is in protocol I probably just need to put the while in the correct place, so that's up first. Thanks folks!
Just to add, the variables are named oddly I'm aware of this it was previously a knock knock joke server
Protocol
import java.util.*;
public class KKProtocol {
int guess = 0, number = new Random().nextInt(100) + 1;
int score = 0;
Scanner scan = new Scanner(System.in);
public String processInput(String theInput) {
String theOutput = null;
System.out.println("Please guess the number between 1 and 100.");
while (guess != number) {
try {
if ((guess = Integer.parseInt(scan.nextLine())) != number) {
System.out.println(guess < number ? "Higher..." : "Lower...");
}
else {
System.out.println("Correct!");
score = 1;
}
}
catch (NumberFormatException e) {
System.out.println("Please enter a valid number! If you want to Quit just say'Goodbye'");
}
}
return theOutput;
}}
Server
import java.net.*;
import java.io.*;
public class KKServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4040);
} catch (IOException e) {
System.err.println("Could not listen on port: 4040.");
System.exit(-1);
}
System.err.println("Started KK server listening on port 4040");
while (listening)
new KKThread(serverSocket.accept()).start();
System.out.println("Accepted connection from client");
serverSocket.close();
}
}
Thread
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class KKThread extends Thread {
private Socket mySocket = null;
public KKThread(Socket inSocket) { //super("KKThread");
mySocket = inSocket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true);
Scanner in = new Scanner(mySocket.getInputStream());
String inputLine, outputLine;
KKProtocol kkp = new KKProtocol();
outputLine = kkp.processInput(null); // first time only
out.println(outputLine); // (Should be "Knock Knock")
while (true) {
inputLine = in.nextLine(); // read in client input
outputLine = kkp.processInput(inputLine); // get reply from protocol
out.println(outputLine); // send it out to socket
if (outputLine.equals("Bye"))
break;
}
out.close();
in.close();
mySocket.close();
} catch (Exception e) {
System.err.println("Connection reset"); //e.printStackTrace();
}
}
}
Client
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class KKClient {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
Scanner in = null;
try {
kkSocket = new Socket("127.0.0.1", 4040);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new Scanner(new InputStreamReader(kkSocket.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 for the connection");
System.exit(1);
}
Scanner stdIn = new Scanner(System.in);
String fromServer = in.nextLine();
while (true) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
out.println(stdIn.nextLine());
fromServer = in.nextLine();
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
'
Why does it jump to the server and says 'server null'? How do I continue the guessing until the client inputs 'goodbye'?
You are currently not assigning the server response for the score in KKProtocol.processInput() so a null is returned instead resulting in the message that you see:
Server: null
You could use:
theOutput = Integer.toString(score);
Also your score is fixed at 1 so you may wish to devise a scoring system perhaps based on the number of guesses used.
In you processInput()method, you are not returning any value, but allways null.
It looks like that null value is transformed into the String "null" on output and sent to the client.
Related
I'm doing a school project where we are supposed to create a simplefied Hotel booking system and then use it with a server/client communication.
Since I wanted to push the project a bit and do a multithreaded program, I've got a Socket Exception that I'm not sure how to handle. I've searched everywhere for an answer and I know that the exception occours because I'm trying to use a socket that has been closed. But from what I've read on Oracle-docs, their example is doing that as well.
So, is this actually Ok, just that I need to handle the exception? Cause my code runs fine, I just see the exceptions since I've put e.printStackTrace(); in my catch.
My Client class:
package client;
import java.io.*;
import java.net.Socket;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
Socket client = new Socket("localhost", 6066);
//System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
LocalDate localDate = LocalDate.now();
String date = DateTimeFormatter.ofPattern("yyy/MM/dd").format(localDate);
System.out.println(in.readUTF());
System.out.print("Namn: ");
String name = sc.nextLine();
System.out.print("Ålder: ");
String age = sc.nextLine();
out.writeUTF(name);
out.writeUTF(age);
out.writeUTF(date);
System.out.println(in.readUTF());
client.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
And my Server class:
package server;
import java.io.IOException;
import java.net.*;
public class Server {
public static void main(String [] args) throws IOException {
int port = 6066;
ServerSocket server = new ServerSocket(port);
while(true) {
System.out.println("Listening for client..");
try {
Socket connectedClient = server.accept();
ClientHandle ch = new ClientHandle(connectedClient);
Thread t = new Thread((Runnable) ch);
t.start();
}catch (IOException e) {
}
}
}
}
And then my ClientHandle class which has the run() for the server-side:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import resources.*;
public class ClientHandle implements Runnable{
Socket connectedClient;
DataInputStream in;
DataOutputStream out;
public ClientHandle(Socket connectedClient) {
this.connectedClient = connectedClient;
try{
this.in = new DataInputStream(this.connectedClient.getInputStream());
this.out = new DataOutputStream(this.connectedClient.getOutputStream());
}catch(IOException ex) {
}
}
Hotel hotel = new Hotel();
Ticket yourTicket = new Ticket();
Server server = new Server();
#Override
public void run() {
while (true) {
try {
InetAddress host = InetAddress.getLocalHost();
System.out.println("Client " + host + " has connected.");
out.writeUTF("Välkommen till Hotel Gisslevik!\nVänligen fyll i nedan information för att slutföra din bokning.\n");
String yourName = in.readUTF();
String age = in.readUTF();
int yourAge = Integer.parseInt(age);
String date = in.readUTF();
yourTicket.setDate(date);
Person guest = new Person(yourName, yourAge);
hotel.setRooms();
Integer room = hotel.getRoom();
String rent = "J";
if (rent.indexOf("J") >= 0) {
yourTicket.setId(yourName);
if (hotel.checkIn(guest, room, yourTicket.getId(), yourTicket.getDate())) {
String yourId = yourTicket.getId();
out.writeUTF("\nDitt rum är nu bokat den " + date + ". \nBokningsnummer: " + yourId);
}
}
out.flush();
connectedClient.close();
}catch (EOFException e) {
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
If I just comment e.printStackTrace(); the exceptions doesn't show, but I would like to know how to handle them (if they should be handled). I've been searching the internet for days and checked out tutorials, but I don't find a proper answer to this.
I really appreciate any help you can provide.
Handle java.net.SocketException: Socket closed
Don't close the socket and then continue to use it.
when multithreading?
Irrelevant.
You have connectedClient.close() inside your while (true) loop. Solution: move it outside.
There is a string called numberPart inside a thread class called ServerRecieve. The location where .start() is being called is inside of a different class called Server.
The 'numberPart' will eventually be used as a port for file transferring later on.
My question is: How do I access the numberPart variable inside of the class called Server?
Screenshot of code running (server on left window, client on the right):
server on left window, client on the right
In the left window of the screenshot (server) you can see the that the first port number of the right window's command line argument which is 4021 being sent via a text message, and the server successfully receives it with the message "File transfer port found: 4021". Unfortunately this variable is located inside a different class. I would like to know how to access that variable inside the class called Server.
ServerRecieve code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerRecieve extends Thread
{
Socket servSocket;
boolean m_bRunThread = true;
boolean ServerOn = true;
public ServerRecieve(Socket s)
{
super();
servSocket = s;
}
public void run()
{
while(true)
{
try
{
BufferedReader readFromClient = new BufferedReader(new InputStreamReader(servSocket.getInputStream()));
String fromClient = readFromClient.readLine();
String a = fromClient;
int i;
for(i = 0; i < a.length(); i++)
{
char c = a.charAt(i);
if( '0' <= c && c <= '9' )
{
break;
}
}
String alphaPart = a.substring(0, i);
String numberPart = a.substring(i);
System.out.println("Recieved from client: " + alphaPart +"\n");
System.out.println("File transfer port found: " + numberPart + "\n");
//String[] filePortNumber = null;
//filePortNumber[0] = numberPart;
// Server thing = new Server(filePortNumber);
if(fromClient.equals(null))
{
System.exit(0);
}
OutputOptions();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
}
void OutputOptions()
{
System.out.println("Enter an option ('m', 'f', 'x'): ");
System.out.println("(M)essage (send)");
System.out.println("(F)ile (request) ");
System.out.println("e(X)it ");
}
}
Server source:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.IIOException;
public class Server
{
private String[] serverArgs;
public Socket socket;
public Socket fileSocket;
public boolean keepRunning = true;
public int ConnectOnce = 0;
public String option = "";
public boolean isConnected = false;
public String FILE_TO_SEND = "/Users/nanettegormley/Documents/workspace/assignment2/src/servers/cdm.jpg";
public Server(String[] args) throws IOException
{
// set the instance variable
this.serverArgs = args;
if(ConnectOnce == 0)
{
int port_number1 = Integer.valueOf(serverArgs[1]);
ServerSocket serverSocket = new ServerSocket(port_number1);
socket = serverSocket.accept();
ConnectOnce = 4;
isConnected = true;
}
}
public String[] serverRun2(String[] args) throws IOException
{
serverArgs = args;
serverArgs = Arrays.copyOf(args, args.length);
serverSend.start();
return serverArgs;
}
Thread serverSend = new Thread()
{
public void run()
{
OutputOptions();
while(isConnected)
{
try
{
ServerRecieve serverThread = new ServerRecieve(socket);
serverThread.start();
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
option = input2.readLine();
if(option.equals("m") || option.equals("M"))
{
StandardOutput();
}
if(option.equals("f") || option.equals("F"))
{
FileTransferSend();
}
if(option.equals("x") || option.equals("X"))
{
System.exit(0);
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
}
}
};
public void StandardOutput()
{
try
{
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
System.out.println("Enter your message: ");
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
String line = "";
line= input2.readLine();
newmessage += line + " ";
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.newLine();
bw.flush();
System.out.println("Message sent to client: "+sendMessage);
StandardInput();
//run();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
void FileTransferSend()
{
//connect to the filetransfer
try
{
System.out.println("Which file do you want? ");
Scanner scanner = new Scanner(System.in);
String filename = scanner.nextLine();
FileInputStream fis = new FileInputStream(new File(filename));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(fileSocket.getOutputStream()));
int element;
while((element = fis.read()) !=1)
{
dos.write(element);
}
byte[] byteBuffer = new byte[1024]; // buffer
while(fis.read(byteBuffer)!= -1)
{
dos.write(byteBuffer);
}
OutputOptions();
// dos.close();
// fis.close();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
void OutputOptions()
{
System.out.println("Enter an option ('m', 'f', 'x'): ");
System.out.println("(M)essage (send)");
System.out.println("(F)ile (request) ");
System.out.println("e(X)it ");
}
public void StandardInput()
{
OutputOptions();
while(true)
{
try
{
// input the message from standard input
BufferedReader input2= new BufferedReader(new InputStreamReader(System.in));
String line2 = "";
option= input2.readLine();
if(option.equals("m") || option.equals("M"))
{
StandardOutput();
}
if(option.equals("f") || option.equals("F"))
{
FileTransferSend();
}
if(option.equals("x") || option.equals("X"))
{
System.exit(0);
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
finally
{
}
}
}
}
Full code with all files:
https://www.dropbox.com/s/0yq47gapsd3dgjp/folder33.zip?dl=0
My question is: What changes can I make to the code that would allow me to access numberPart while being inside Server?
EDIT: Is there a way to bump a question that hasn't gotten any answers or should I just delete this one and repost it somewhere?
I would think that you could use either a listener or callback pattern to solve this.
(I'm losing my Java memory now that I'm doing C# so please bear with me..)
interface PortAssignable {
public assignPort(int port);
}
Then have the Server class implement that interface
public Server implements PortAssignable {
...
}
And ServerReceive
// Constructor
public ServerRecieve(Socket s, PortAssignable portNotifyListener) {
_portNotifyListener = portNotifyListener;
... your other code ...
}
Make sure when you create an instance of ServerReceive, you pass in your Server instance, via this.
ServerRecieve serverThread = new ServerRecieve(socket, this);
Now, when you get your numberPart, your next line can be
_portNotifyListener.assignPort(numberPart);
How you choose to implement the assignPort method in your Server class is up to you.
P.S. I saw this question from /r/programming.
My task is to display three options to the user 1)connect to server 2)post data 3)disconnect. I am having trouble in sending the file to the server. "The file needs to be sent from client to server". I am new to socket programming and however I try the connection is being reset while I try to send the file to server.
server
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class Server extends Thread {
private ServerSocket serverSocket;
public Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
public void run() {
boolean flag = true;
while (flag) {
try {
System.out.println("Waiting for client on port "
+ serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
Scanner reader = new Scanner(server.getInputStream());
File file = new File("compile.txt");
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(
file));
while (reader.hasNextLine()) {
String str = reader.next();
fileWriter.write(str);
System.out.println("" + str);
}
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
int port = 4444;
try {
Thread t = new Server(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
client
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class Client {
public static void main(String[] args) {
Socket client = null;
boolean flag = true;
while (flag) {
System.out
.println("Please enter your choice\n1.Connect to Server\n2.Post Data\n3.Disconnect from Server");
Scanner userChoice = new Scanner(System.in);
int choice = userChoice.nextInt();
String serverName = "localhost";
int port = 4444;
if (choice == 1) {
try {
System.out.println("Connecting to " + serverName
+ " on port " + port);
client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
} catch (IOException e) {
e.printStackTrace();
}
} else if (choice == 2) {
System.out.println("enter path of file to be compiled");
Scanner pathReader = new Scanner(System.in);
String path = pathReader.next();
pathReader.close();
String line;
try {
BufferedReader br = new BufferedReader(new FileReader(path));
while ((line = br.readLine()) != null) {
PrintWriter writer = new PrintWriter(
client.getOutputStream(), true);
writer.write(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
client.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (choice == 3) {
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
System.out.println("enter a valid input");
}
}
}
First of all client-server socket connections and applications are pretty complicated. I'd recommend reading:
http://www.oracle.com/technetwork/java/socket-140484.html#sockets
couple of things to consider:
make sure there is nothing running on the socket.
make sure that the server is listening
You are running the server on one thread, so if it finishes at all then it won't restart
You are not closing the fileWriter once you have finished writing -
please post your output/any stacktraces you have
So I did this client server program in java for my college mini project. Note that this is just a small module of a big project I'm working on. I need a string to be sent from the client to the server. The server will return back the string as it is back to the client. (The code will be modified later such that the string is processed before sending back). The client will send a string whenever needed to the server. Thus it means it is compulsory for the server to be running for indefinite time.
The problem I face here is that my server works perfectly only for the first time when the client sends a string. If I run the client the second time with a different string, I get back the same string I sent to the server previously!
Here is my server program:
public class Server {
public static boolean x = true;
public static String reply;
public static void main(String a[]) throws Exception {
System.out.println("Entered server console..");
Socket echoSocket = null;
ServerSocket serverSocket = null;
PrintWriter out = null;
BufferedReader in = null;
System.out.println("Initializing Connection..");
boolean runFlag = true;
try {
serverSocket = new ServerSocket(77);
while (runFlag) {
echoSocket = serverSocket.accept();
out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
while (x) {
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
reply = in.readLine();
if (reply != null) {
x = false;
}
}
System.out.println("received: " + reply);
out.println(reply);
System.out.println("sent back: " + reply);
stdIn.close();
}
} catch (Exception e) {
System.out.println("Exception in starting server: " + e.getMessage());
} finally {
out.close();
in.close();
echoSocket.close();
}
}
}
Here is my Client program:
public class Client {
public static String reply,temp;
public static boolean x=true;
public Client()
{
temp="lala";
}
public Client(String t)
{
temp=t;
}
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("localhost", 77);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: localhost.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
temp="lala"; //this is the string to be sent
out.println(temp);
while (x) {
reply= in.readLine();
if(reply!=null)
{
x=false;
}
}
System.out.println("reply: "+reply);
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
Can anyone help me find what the problem here is?
while (x) {
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
reply = in.readLine();
if (reply != null) {
x = false;
}
}
Your server enters this loop the first time a client connects, and it sets the reply String to some input from the client. However, it never enters this loop again, as x's value never changes back to true.
When you accept a request, the x will be set false and never become true.
Please initial the x when you enter the loop.
What's more,if you use a socket between client and server, please move the
echoSocket = serverSocket.accept();
out of the first loop.And you can use echoSocket to communicate.Then you will
keep the long connection.
I wrote this simple Java program which connects to internic server and returns the domain details. However, I am facing a strange problem. I may sound dumb but here is the program!
import java.io.*;
import java.net.*;
public class SocketTest {
public static void main(String[] args) {
String hostName;
int i = 0;
try {
Socket socketClient = new Socket("whois.internic.net", 43);
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
InputStream in = socketClient.getInputStream();
OutputStream out = socketClient.getOutputStream();
System.out.println("Please Enter the Host Name!!");
hostName = bf.readLine();
hostName = hostName + "\n";
byte[] buf = hostName.getBytes();
out.write(buf);
while((i = in.read()) != -1) {
System.out.print((char)i);
}
socketClient.close();
} catch(UnknownHostException uht) {
System.out.println("Host Error");
} catch(IOException ioe) {
System.out.println("IO Error " + ioe);
} catch(Exception e) {
System.out.println("Exception " + e);
}
}
}
The program runs fine, without any runtime errors, but it shows no output when I try to print the result from internic server in the last piece of try block. I tried rearranging the code and found that if I place the bf.readLine() after creating socket streams, there is no output. However, if I place it before the socket creation (at the start of main method), the program displays intended output.
Is there any stream conflict or so? I am a newbie to networking in Java. The solution may be obvious but I am not able to understand! Please help me!!!
Move your input stream initialization after you send the domain to the output stream... This works for me locally:
import java.io.*;
import java.net.*;
public class SocketTest {
public static void main(String[] args) {
String hostName;
int i = 0;
try {
Socket socketClient = new Socket("whois.internic.net", 43);
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
OutputStream out = socketClient.getOutputStream();
System.out.println("Please Enter the Host Name!!");
hostName = bf.readLine();
hostName = hostName + "\n";
byte[] buf = hostName.getBytes();
out.write(buf);
InputStream in = socketClient.getInputStream();
while ((i = in.read()) != -1) {
System.out.print((char) i);
}
in.close();
out.close();
socketClient.close();
} catch (UnknownHostException uht) {
System.out.println("Host Error");
} catch (IOException ioe) {
System.out.println("IO Error " + ioe);
} catch (Exception e) {
System.out.println("Exception " + e);
}
}
}
Output:
Please Enter the Host Name!!
yahoo.com
Whois Server Version 2.0
Domain names in the .com and .net domains can now be registered
with many different competing registrars. Go to http://www.internic.net
for detailed information.
YAHOO.COM.ZZZZZZZ.GET.ONE.MILLION.DOLLARS.AT.WWW.UNIMUNDI.COM
YAHOO.COM.ZZZZZZ.MORE.INFO.AT.WWW.BEYONDWHOIS.COM
....Whole bunch more