Server not receiving requests from client - java

Basically I'm writing a 2 way communication client server program. The client sends requests to the server and server responds accordingly. The requests have to do with adding or removing tokens from a list of tokens stored on the server. The client side seems to work fine, the requests are being sent to the server. However it seems that the server is not receiving any request from the client and I have no idea why. I've attached the code:
client
package;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class TokenClient {
private static final int PORT_NUMBER = 9999;
private Socket socket;
private InputStream inStream;
private OutputStream outStream;
private Scanner inStreamScanner;
private PrintWriter outStreamPrinter;
public static void main(String[] args) {
new TokenClient().go();
}
void go() {
try {
System.out.println(
"Enter commands of the form \"CONNECT IP-address\", \"SUBMIT token\", \"REMOVE token\" or \"QUIT\"\n");
Scanner consoleScanner = new Scanner(System.in);
// java.io.BufferedReader consoleInputReader = new
// BufferedReader(new InputStreamReader(System.in));
String command = "";
while (!command.equals("QUIT") && consoleScanner.hasNextLine()) {
command = consoleScanner.nextLine(); // consoleInputReader.readLine();
processCommand(command);
}
System.out.println("Goodbye!");
consoleScanner.close();
} catch (IOException e) {
System.out.println("An exception occurred: " + e);
e.printStackTrace();
}
}
void processCommand(String userCommand) throws IOException {
if (userCommand.startsWith("SUBMIT"))
sendMessageToServer(userCommand);
else if (userCommand.startsWith("REMOVE"))
sendMessageToServer(userCommand);
else if (userCommand.equals("QUIT"))
closeConnectionToServer();
else if (userCommand.startsWith("CONNECT")) {
closeConnectionToServer();
connectToServer(userCommand);
} else
System.out.println("Invalid user command: " + userCommand);
}
void closeConnectionToServer() {
if (socket != null && !socket.isClosed()) {
try {
System.out.println("Disconnecting from server...");
sendMessageToServer("QUIT");
socket.close();
System.out.println("Connection to server closed.");
} catch (IOException e) {
System.out.println("An exception occurred: " + e);
e.printStackTrace();
}
}
}
void connectToServer(String connectCommand) throws IOException {
String ipAddress = connectCommand.substring(8).trim();
System.out.println("Connecting to server at " + ipAddress + ", port " + PORT_NUMBER + "...");
socket = new Socket(ipAddress, PORT_NUMBER);
inStream = socket.getInputStream();
outStream = socket.getOutputStream();
inStreamScanner = new Scanner(inStream);
outStreamPrinter = new PrintWriter(outStream);
System.out.println("Connected to server.");
}
void sendMessageToServer(String command) {
System.out.println("Sending message to server: " + command + "...");
if (socket == null || socket.isClosed())
System.out.println("Not possible - not connected to a server");
else {
outStreamPrinter.println(command); // send the message to the server
// NB: client doesn't check if tokens are valid
outStreamPrinter.flush(); // do so immediately
// Receive response from server:
if (!command.equals("QUIT") && inStreamScanner.hasNextLine()) {
String response = inStreamScanner.nextLine();
System.out.println("Response from server: " + response);
}
}
}
}
server
package;
import java.net.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.*;
public class server {
private static Socket s;
private static Scanner inStreamScanner;
private static int PORT_NUMBER = 9999;
private static InputStream inStream;
private static OutputStream outStream;
private static PrintWriter outStreamPrinter;
private static ArrayList<String> ts = new ArrayList<String>();
public static void main(String[] args) throws IOException{
ServerSocket ss = new ServerSocket(PORT_NUMBER);
server serverInstance = new server();
server.s = ss.accept();
System.out.println("Client connected");
inStream = s.getInputStream();
outStream = s.getOutputStream();
inStreamScanner = new Scanner(inStream);
outStreamPrinter = new PrintWriter(outStream);
serverInstance.run();
}
public void run() {
try {
try {
doService();
} finally {
s.close();
}
} catch (IOException e) {
System.err.println(e);
}
}
public void doService() throws IOException{
while(true) {
if(inStreamScanner.hasNext())
return;
else {
outStreamPrinter.println("NO REQUEST");
outStreamPrinter.flush();
String request = inStreamScanner.next();
outStreamPrinter.println("Request received: " +request);
outStreamPrinter.flush();
handleServerRequest(request);
}
}
}
public void handleServerRequest(String request) throws IOException{
if(request.startsWith("SUBMIT")) {
String token = extractNum(request);
addtoTS(token);
} else if(request.startsWith("REMOVE")) {
String token = extractNum(request);
removefromTS(token);
} else if(request.startsWith("QUIT")) {
s.close();
} else {
outStreamPrinter.println("UNKNOWN REQUEST");
outStreamPrinter.flush();
}
}
public String extractNum(String request) {
String str = request;
String numberOnly = str.replaceAll("[^0-9]", " ");
return numberOnly;
}
public void addtoTS(String token) {
if(ts.contains(token)) {
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}else {
ts.add(token);
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}
}
public void removefromTS(String token) {
if(ts.contains(token)) {
ts.remove(token);
outStreamPrinter.println("OK");
outStreamPrinter.flush();
}else {
outStreamPrinter.println("ERROR: TOKEN NOT FOUND");
outStreamPrinter.flush();
}
}
}

I haven't run the code, but there seems to be an issue in your doService() method on the server side. You have an infinite loop, but the entire method returns (and thus the program also quits) as soon as the input stream recieves a new line character (when the client sends a request). So, it seems your program would quit when it receives the first command from the client. I'd also recommend closing more gently (ie check in the loop for end rather than closing the socket directly).
So, I'd define a private class variable boolean listening; or something like that. Then in the main() method, set it to true after the socket has been initialized (when the client has connected).
Change your doService() to something similar to the following:
public void doService() throws IOException
{
while(listening)
{
if(inputStreamReader.hasNext())
{
String request = inStreamScanner.next();
outStreamPrinter.println("Request received: " +request);
outStreamPrinter.flush();
handleServerRequest(request);
}
}
}
And change how you handle the QUIT command:
from
else if(request.startsWith("QUIT"))
{
s.close();
}
to
else if(request.startsWith("QUIT"))
{
listening = false;
}
The socket will be closed by the finally in run().

Related

Java - Client-server program - http response

I'm new to coding and Java,I have create a simple client-server program where the client can request a file. Its content will be displayed in the browser page together with some details like the data type and the length.
I'm now having a problem, I'm not sure how to display in the browser the server response for a correct connection like "HTTP/1.1 200 OK" and for the connection closed like "Connection: close".
I have a method to handle the response as follow:
import java.io.*;
import java.net.*;
import java.util.*;
public class ReadRequest {
private final static int LISTENING_PORT = 50505;
protected static Socket client;
protected static PrintStream out;
static String requestedFile;
#SuppressWarnings("resource")
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(LISTENING_PORT);
}
catch (Exception e) {
System.out.println("Failed to create listening socket.");
return;
}
System.out.println("Listening on port " + LISTENING_PORT);
try {
while (true) {
Socket connection = serverSocket.accept();
System.out.println("\nConnection from "+ connection.getRemoteSocketAddress());
ConnectionThread thread = new ConnectionThread(connection);
thread.start();
}
}
catch (Exception e) {
System.out.println("Server socket shut down unexpectedly!");
System.out.println("Error: " + e);
System.out.println("Exiting.");
}
}
private static void handleConnection(Socket connection) {
String username = System.getProperty("user.name");
String httpRootDir = "C:\\Users\\"+(username)+"\\Downloads\\";
client = connection;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintStream (client.getOutputStream());
String line = null;
String req = null;
req = in.readLine();
line = req;
while (line.length() > 0)
{
line = in.readLine();
}
StringTokenizer st = new StringTokenizer(req);
if (!st.nextToken().equals("GET"))
{
sendErrorResponse(501);
return;
}
requestedFile = st.nextToken();
File f = new File(httpRootDir + requestedFile);
if (!f.canRead())
{
sendErrorResponse(404);
return;
}
sendResponseHeader(getMimeType(requestedFile),(int) f.length());
sendFile(f,client.getOutputStream());
}
catch (Exception e) {
System.out.println("Error while communicating with client: " + e);
}
finally {
try {
connection.close();
}
catch (Exception e) {
}
System.out.println("Connection closed.");
};
}
private static void sendResponseHeader(String type,int length)
{
out.println("Content-type: " +type+"\r\n");
out.println("Content-Length: " +length+"\r\n");
}
private static void sendErrorResponse(int errorCode)
{
switch(errorCode) {
case 404:
out.print("HTTP/1.1 404 Not Found");
out.println("Connection: close " );
out.println("Content-type: text/plain" +"\r\n");
out.println("<html><head><title>Error</title></head><body> <h2>Error: 404 Not Found</h2> <p>The resource that you requested does not exist on this server.</p> </body></html>");
break;
case 501:
out.print("HTTP/1.1 501 Not Implemented");
out.println("Connection: close " );
out.println("Content-type: text/plain" +"\r\n");
break;
}
}
private static String getMimeType(String fileName) {
int pos = fileName.lastIndexOf('.');
if (pos < 0)
return "g-application/x-unknown";
String ext = fileName.substring(pos+1).toLowerCase();
if (ext.equals("txt")) return "text/plain";
else if (ext.equals("html")) return "text/html";
else if (ext.equals("htm")) return "text/html";
else if (ext.equals("css")) return "text/css";
else if (ext.equals("js")) return "text/javascript";
else if (ext.equals("java")) return "text/x-java";
else if (ext.equals("jpeg")) return "image/jpeg";
else if (ext.equals("jpg")) return "image/jpeg";
else if (ext.equals("png")) return "image/png";
else if (ext.equals("gif")) return "image/gif";
else if (ext.equals("ico")) return "image/x-icon";
else if (ext.equals("class")) return "application/java-vm";
else if (ext.equals("jar")) return "application/java-archive";
else if (ext.equals("zip")) return "application/zip";
else if (ext.equals("xml")) return "application/xml";
else if (ext.equals("xhtml")) return"application/xhtml+xml";
else return "g-application/x-unknown";
}
private static void sendFile(File file, OutputStream socketOut) throws IOException {
try (InputStream infile = new BufferedInputStream(new FileInputStream(file))) {
OutputStream outfile = new BufferedOutputStream(socketOut);
while (true) {
int x = infile.read();
if (x < 0)
break;
outfile.write(x);
}
outfile.flush();
}
}
private static class ConnectionThread extends Thread {
Socket connection;
ConnectionThread(Socket connection) {
this.connection = connection;
}
public void run() {
handleConnection(connection);
}
}
}
Any suggestion on how I can do that? thank you
You make your way too complicate if you try to reinvent the wheel implementing Request/Response communication. It is better just to use the Spring MVC.

java server Socket sending data to wrong Client

As the title says if you try to execute this program, start 2 clients, and try to send a message 'login' or 'register' with the first client the server will receive the input but redirect the response to the second socket (the last one who connected). You can see this by looking at the port number printed on Server console when Server tries to send response to client
public class Server {
private ServerSocket server;
public Server() {
try {
server = new ServerSocket(10000);
System.out.println("[INFO] server running");
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Server server = new Server();
server.run();
}
public void run() {
try {
while (true) {
Socket clientRequest = server.accept();
new Thread(new ServerThread(clientRequest)).start();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
class ServerThread implements Runnable {
private static Socket socket;
private static Connection dbConnection = null;
private static OutputStream outputStream;
private static ObjectOutputStream objectOutputStream;
private static InputStream inputStream;
private static ObjectInputStream objectInputStream;
private static List<String> messages = new ArrayList<String>();
private static MessageDigest messageDigest;
private static String username = "";
private static boolean invalidUsername;
public ServerThread(Socket richiestaClient) {
try {
socket = richiestaClient;
System.out.println("[INFO] " + socket + " connected ");
outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputStream = socket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
} catch (IOException e) {
System.out.println("[ERROR] errore di i/o");
}
}
public void run() {
// conversazione lato server
try {
boolean active = true;
while (active) {
System.out.println("[THREAD] " + Thread.currentThread().getName());
System.out.println("[DEBUG] current socket: " + socket);
String msg = (String) objectInputStream.readObject();
System.out.println("[CLIENT] " + msg);
// -- SELECT CASE FOR USER LOGIN/REGISTER --
switch (msg) {
case "login":
login(dbConnection);
break;
case "register":
register(dbConnection);
break;
default:
break;
}
}
} catch (IOException | ClassNotFoundException e) {
System.out.println("[ERROR] errore nello switch azioni ioexception " + e);
}
}
private static void register(Connection dbConnection) {
System.out.println("[THREAD] " + Thread.currentThread().getName());
System.out.println("[DEBUG] client selected register " + socket);
messages.add("username");
messages.add("You selected register");
invalidUsername = true;
while (invalidUsername) {
messages.add("input the username you want");
send(messages);
// getting username (assuming not taken for testing purpose)
boolean usernameExists = false;
if (usernameExists) {
System.out.println("[DEBUG] username exists, not available for the registration");
messages.add("username");
messages.add("sorry, username is taken :(");
} else {
System.out.println("[DEBUG] username does not exists, available for the registration");
messages.add("password");
messages.add("username is not taken yet :)");
invalidUsername = false;
}
}
System.out.println("[DEBUG] username not taken, sending result to " + socket);
}
private static void login(Connection dbConnection) {
System.out.println("[THREAD] " + Thread.currentThread().getName());
System.out.println("[DEBUG] client selected login " + socket);
messages.add("username");
messages.add("You selected login");
messages.add("Input your username");
send(messages);
try {
username = (String) objectInputStream.readObject();
System.out.println("[INFO] received " + username + " from " + socket);
} catch (ClassNotFoundException | IOException e) {
System.out.println("[DEBUG] error while waiting for client login username");
}
}
// sending messages, flushing stream and clearing messages list
private static void send(List<String> messagesToSend) {
System.out.println("[THREAD] " + Thread.currentThread().getName());
System.out.println("[DEBUG] Sending data to " + socket);
try {
objectOutputStream.writeObject(messagesToSend);
objectOutputStream.flush();
messages.clear();
} catch (IOException e) {
System.out.println("[ERROR] error occurred while sending message");
}
}
}
public class Client {
private static Socket socket;
private static OutputStream outputStream;
private static ObjectOutputStream objectOutputStream;
private static InputStream inputStream;
private static ObjectInputStream objectInputStream;
public Client() {
try {
socket = new Socket("127.0.0.1", 10000);
outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputStream = socket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Client client = new Client();
client.conversazione();
}
public void conversazione() {
// conversazione lato client
Scanner scan = new Scanner(System.in);
String command = "default";
String message = "";
String username = "";
List<String> messages = new ArrayList<String>();
System.out.println("what do you want to do? (login/register)");
while (true) {
try {
switch (command) {
case "default":
System.out.println("[DEBUG] switch option: default");
message = scan.nextLine();
send(message);
break;
case "username":
System.out.println("[DEBUG] switch option: username");
username = scan.nextLine();
send(username);
break;
case "password":
System.out.println("[DEBUG] switch option: password");
// not implemented yet
break;
default:
break;
}
// getting messages from the server, using the first one as "header" to know what to do
System.out.println("[DEBUG] waiting for message " + socket);
messages = (List<String>) objectInputStream.readObject();
System.out.println("Received [" + (messages.size() - 1) + "] messages from: " + socket);
command = messages.get(0);
messages.remove(0);
for (String msg : messages) {
System.out.println(msg);
}
messages.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// send message to the server and reset the stream
public static void send(String message) {
try {
System.out.println("[DEBUG] sending data as " + socket);
objectOutputStream.writeObject(message);
objectOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The "static" keyword in attributes means that the value of the attribute is spread over all objects of the class, since the value is not stored in the object, but, simply put, is stored in the class.
If you don't know exactly what "static" stands for, maybe check out the following page: Static keyword in java
public class Test {
// static attribute
private static String hello = "world";
public void setHello(String newValue) {
Test.hello = newValue;
}
public void printHello() {
System.out.println(Test.hello);
}
}
public class Main {
public static void main(String[] args) {
Test test1 = new Test();
Test test2 = new Test();
test1.printHello(); // -> "world"
test2.printHello(); // -> "world"
// Note that we seem to change only the value of "hello" in object "test1".
// However, since the attribute "test1" is static, the value "changes" for all objects of the class.
test1.setHello("StackOverflow");
test1.printHello(); // "StackOverflow"
test2.printHello(); // "StackOverflow" <- same as in "test1"
}
}
The problem is that in your "ServerThread" class all attributes are static, and therefore they are shared across different objects. So if you overwrite the variable "socket" in client 2, you overwrite "socket" on for client 1.
So remove the "static" keyword from attributes and methods of the Client and ServerThread class and that should solve the problem.

Getting java.net.SocketException Connection reset error in socket communication with threads

I'm basically trying to code a socket communication between multiple clients and a server.
I am getting this error java.net.SocketException: Connection reset. I have read some posts regarding this error, but none of the proposed solutions seems to solve my problem.
Here is the code for the Client : Client.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import javafx.scene.web.PromptData;
public class Client {
private Socket socket;
private boolean running;
public Client(Socket socket) {
this.socket = socket;
running = true;
}
public void sendToServer(String message) throws IOException {
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
outputStream.writeUTF(message);
System.out.println("Die Nachricht : \"" + message + "\" wurde zu dem Server geschickt.");
// outputStream.close();
}
public String waitForNewMessage() throws IOException {
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
String message = inputStream.readUTF();
// inputStream.close();
return message;
}
public void stop() throws IOException {
socket.close();
running = false;
}
public boolean isRunning() {
if (running == true) {
return true;
}
return false;
}
public String promptForNewMessage() {
Scanner scanner = new Scanner(System.in);
System.out.println("Geben Sie eine Nachricht ein.");
String message = scanner.nextLine();
scanner.close();
return message;
}
public void processReceivedMessage(String message) {
System.out.println("Hier ist die Antwort des Servers : " + message);
}
public static void main(String[] args) throws IOException {
//Socket clientSocket = new Socket(args[0], Integer.parseInt(args[1]));
Socket clientSocket = new Socket("localhost",9999);
Client client = new Client(clientSocket);
while (true) {
String message = client.promptForNewMessage();
client.sendToServer(message);
String response = client.waitForNewMessage();
client.processReceivedMessage(response);
if(response.contains("\\exit")) {
System.out.println("Die Verbindung wird geschlossen");
client.stop();
break;
}
}
}
}
The code for the server : Server.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
private int port;
private boolean running;
private ServerSocket serverSocket;
private static Server instance;
private Server() throws IOException {
this.port = loadPortFromConfig("config-datei.txt");
this.running = true;
this.serverSocket = new ServerSocket(this.port);
}
public int loadPortFromConfig(String path) throws FileNotFoundException {
File config = new File(path);
Scanner in = new Scanner(config);
if (in.hasNextLine()) {
String line = in.nextLine().split(":")[1];
in.close();
return Integer.parseInt(line);
}
in.close();
return 9999;
}
public static Server getInstance() throws IOException {
if (instance == null) {
instance = new Server();
}
return instance;
}
public static void main(String[] args) throws IOException {
Server server = Server.getInstance();
if (args.length != 0) {
server.port = Integer.parseInt(args[0]);
}
System.out.println("Der Port des Servers ist : " + server.port);
while(true) {
Socket socket = null;
try {
socket = server.serverSocket.accept();
System.out.println("A new client is connected : " + socket);
System.out.println("Assigning a new thread for this client");
Thread t = new Connection(socket);
t.start();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
static class Connection extends Thread {
private Socket clientSocket;
private boolean running;
public Connection(Socket clientSocket) {
this.clientSocket = clientSocket;
this.running = true;
}
#Override
public void run() {
String fromClient = "";
while(true) {
try {
fromClient = waitForMessage();
System.out.println("Der Client hat die Nachricht : \"" + fromClient + "\" geschickt");
if(fromClient.contains("\\exit")) {
System.out.println("Client "+this.clientSocket + "sneds exit...");
System.out.println("Closing connection.");
sendToClient(fromClient);
System.out.println("Connection closed");
running = false;
break;
}
sendToClient(fromClient);
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public String waitForMessage() throws IOException {
DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
String message = inputStream.readUTF();
// inputStream.close();
return message;
}
public void sendToClient(String message) throws IOException {
DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
outputStream.writeUTF("Die folgende Nachricht : \"" + message + "\" wurde geschickt");
// outputStream.close();
}
}
}
The error occurs in the line fromClient = waitForMessage(); in the try catch block of the server code
This code calls the method waitForMessage() in the line : String message = inputStream.readUTF();
Do you have any recommendations ? thank you
java.net.SocketException: Connection reset
This means the OS has reseted the connection because the process on the other end is no longer running. It looks like your client crashes after processing first reply from the server.
Scanner scanner = new Scanner(System.in);
scanner.close();
Do not close Scanners operating on System.in. This will close System.in and you will not be able to read anything anymore from there.

Java Webserver not responding

Goal:
My goal with this code is to create a simple web server that can handle multiple clients, and that will respond with the html to say "hi" when the client requests it.
Code:
Here's test number one. It only can handle one client once:
import java.net.*;
import java.io.*;
public class Webserver1 {
public static void main(String[] args) {
ServerSocket ss;
Socket s;
try {
//set up connection
ss = new ServerSocket(80);
s = ss.accept();
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
try (
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
DataOutputStream out = new DataOutputStream (s.getOutputStream());
) {
String inline = in.readLine();
//http request
if (inline.startsWith("GET")) {
//return http
out.writeBytes("<!doctype html><html><body><p>hi</p></body></html>");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
Here's test number two. It is meant to handle multiple clients:
import java.net.*;
import java.io.*;
public class Webserver2 {
//class to handle connections
public static class server {
ServerSocket ss;
Socket s[] = new Socket[maxn];
public server () {
try {
ss = new ServerSocket(80);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public InputStream getis(int num) throws Exception {
return s[num].getInputStream();
}
public OutputStream getos(int num) throws Exception {
return s[num].getOutputStream();
}
public void close() throws Exception {
for (int i = 0; i < numc; i++) {
s[i].close();
}
}
public void newc () throws Exception {
s[numc + 1] = ss.accept();
}
}
static int numc = 0;
static final int maxn = 100;
static server se = new server();
public static void main(String[] args) {
try {
while (numc < 6) {
//set up connection, and start new thread
se.newc();
numc++;
System.out.println("0");
(new Client()).start();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static class Client extends Thread {
public void run() {
try(
BufferedReader in = new BufferedReader(new InputStreamReader(se.getis(numc)));
DataOutputStream out = new DataOutputStream (se.getos(numc));
) {
String inline;
while(true) {
inline = in.readLine();
//wait for http request
if (inline.startsWith("GET")) {
System.out.println("1");
//respond with header, and html
out.writeBytes("HTTP/1.1 200 OK\r\n");
out.writeBytes("Connection: close\r\n");
out.writeBytes("Content-Type: text/html\r\n\r\n");
out.writeBytes("<!doctype html><html><body><p>hi</p></body></html>");
out.flush();
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Problems:
On my computer, if I run the first example, and on my browser I type: "http://192.168.1.xxx", I get a simple "hi". However, on the second one if I try the same thing it simply doesn't work. But if in the command prompt I type: telnet 192.168.1.xxx 80, then type GET it sends back the html. Also, if I replace the DataOutputStream with a PrintWriter, it doesn't even send it to the telnet. However, I know it tries because the program prints "0" every time a connection is made, and "1" every time it prints something.
Questions:
What is the problem that prevents the browser from viewing the html?
Does it have to do with the html itself, the way I set up my connection, or the DataOutputStream?
How can I fix this?
Don't use port 80, use some other random port greater than 6000. And if you didn't close your first program properly, port 80 is still used by that program.
I used a Http server program that is similar to this. The server also creates multiple threads for each connections, so the number of clients in not limited to 100.
` public class MultiThreadServer implements Runnable {
Socket csocket;
static int portno;
static String result;
MultiThreadServer(Socket csocket)
{
this.csocket = csocket;
}
public static void main(String args[])
throws Exception
{
portno=Integer.parseInt(args[0]);
ServerSocket srvsock = new ServerSocket(portno);
System.out.println("Listening");
while (true) {
Socket sock = srvsock.accept();
System.out.println("Connected");
new Thread(new MultiThreadServer(sock)).start();
}
}
public void run()
{
String[] inputs=new String[3];
FileInputStream fis=null;
String file=null,status=null,temp=null;
try
{
InputStreamReader ir=new InputStreamReader(csocket.getInputStream());
BufferedReader br= new BufferedReader(ir);
DataOutputStream out = new DataOutputStream(csocket.getOutputStream());
String message=br.readLine();
inputs=message.split(" ");
if(inputs[0].equals("GET"))
{
try{
out.writeBytes("HTTP/1.1 200 OK\r\n");
out.writeBytes("Connection: close\r\n");
out.writeBytes("Content-Type: text/html\r\n\r\n");
out.writeBytes("<!doctype html><html><body><p>hi</p></body> </html>");
}
out.flush();
fis.close();
csocket.close();
}
catch(Exception ex)
{
status="404 File not found";
os.println(status);
}
}`

Chat Program: Client to Client Chat

Currently I'm working on this mini chat program in Java where multiple users should be able to log into the chat program and chat. Right now what my program does is log in users (Clients) to the Server, and what ever they say gets echoed back by the Server. What I want to do is be able to send a request to chat with another client directly.
My idea was to create a Hash map that holds the username of the client and its socket. When a client requests to chat with another client it looks for that user's username in the HashMap and if the other client agrees to chat then it connects the sockets.
I'm not sure how to implement this and also my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why. I've been trying to get this working for a while now, starting to give me headaches.
Here's the code:
Client Class:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class Client implements Runnable {
private Socket socket;
private DataOutputStream dout;
private DataInputStream din;
// Constructor
public Client() {
// Code
}
public Client(String host, int port) {
try {
socket = new Socket(host, port);
System.out.println("connected to " + socket);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
new Thread(this).start();
} catch (IOException ie) {
System.out.println(ie);
}
}
private void processMessage(String message) {
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
public void run() {
try {
while (true) {
String message = din.readUTF();
System.out.println(message);
}
} catch (IOException ie) {
System.out.println(ie);
}
}
public static void main(String[] args) throws IOException {
while (true) {
String prompt;
Scanner clientPrompt = new Scanner(System.in);
System.out.println("client> ");
prompt = clientPrompt.next();
if (prompt.equals("Emmanuel"))
System.out.println("God With Us");
else if (prompt.equals("goOnline")) {
// Enter a host name
// Enter a portNumber
// Enter a userName
String h, p, u;
System.out.println("Enter hostname: ");
h = clientPrompt.next();
System.out.println("Enter portNumber: ");
p = clientPrompt.next();
System.out.println("Enter userName: ");
u = clientPrompt.next();
goOnline(h, p, u);
} else if (prompt.equals("Exit")) {
clientPrompt.close();
System.exit(1);
} else {
System.out.println("Invalid Input, Try Again");
}
}
}
public static void goOnline(String host, String port, String userName) {
int portNumber = Integer.parseInt(port);
Client c = new Client(host, portNumber);
c.processMessage("Username: " + userName);
String prompt;
Scanner clientPrompt = new Scanner(System.in);
while (true) {
prompt = clientPrompt.next();
c.processMessage(prompt);
c.run();
if (prompt.equals("Exit")) {
System.out.println("Bye Bye");
clientPrompt.close();
}
}
}
}
Server Class:
package source;
import java.io.*;
import java.net.*;
import java.util.*;
public class Server { // The ServerSocket we'll use for accepting new
// connections
private ServerSocket ss;
private HashMap<String, Socket> userInfo = new HashMap<String, Socket>();
// A mapping from sockets to DataOutputStreams.
private Hashtable<Socket, DataOutputStream> outputStreams = new Hashtable<Socket, DataOutputStream>();
// Constructor and while-accept loop all in one.
public Server(int port) throws IOException {
// All we have to do is listen
listen(port);
}
private void listen(int port) throws IOException {
// ServerSocket
ss = new ServerSocket(port);
System.out.println("Listening on " + ss);
while (true) {
Socket s = ss.accept();
System.out.println("Connection from " + s);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
DataOutputStream userInfo = new DataOutputStream(s.getOutputStream());
outputStreams.put(s, dout);
outputStreams.put(s, userInfo);
new ServerThread(this, s);
}
}
Enumeration<DataOutputStream> getOutputStreams() {
return outputStreams.elements();
}
void sendToAll(String message) {
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
// Output Stream
DataOutputStream dout = (DataOutputStream) e.nextElement();
// Send Message
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
}
// Remove socket,
void removeConnection(Socket s) {
// Synchronize
synchronized (outputStreams) {
// Tell the world
System.out.println("Removing connection to " + s);
// Remove it from hashtable
outputStreams.remove(s);
try {
s.close();
} catch (IOException ie) {
System.out.println("Error closing " + s);
ie.printStackTrace();
}
}
}
void addInfo(String user, Socket s) {
userInfo.put(user, s);
}
// Main
static public void main(String args[]) throws Exception {
// Get port
int port = Integer.parseInt(args[0]);
// Create Server object
new Server(port);
}
}
ServerThread:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class ServerThread extends Thread { // The Server that spawned us
private Server server;
private Socket socket;
public ServerThread(Server server, Socket socket) {
this.server = server;
this.socket = socket;
start();
}
public void run() {
try {
DataInputStream din = new DataInputStream(socket.getInputStream());
while (true) {
String message = din.readUTF();
StringTokenizer stt = new StringTokenizer(message, " ");
while (stt.hasMoreTokens()) {
String token = stt.nextToken();
if (token.equals("Username:")) {
String username = stt.nextToken();
server.addInfo(username, socket);
}
}
System.out.println("Sending " + message);
server.sendToAll(message);
if (message.equals("Exit")) {
System.out.println("Bye Bye");
server.removeConnection(socket);
System.exit(1);
}
}
} catch (EOFException ie) {
} catch (IOException ie) {
ie.printStackTrace();
} finally {
server.removeConnection(socket);
}
}
}
my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why?
Just do one change as mentioned below at client side to resolve above issue.
public void run() {
try {
// while (true) { // remove an infinite loop that will block
// the client thread to accept next message
String message = din.readUTF();
System.out.println(message);
// }
} catch (IOException ie) {
System.out.println(ie);
}
}
Doubt: (client side)
You have started a thread then why are you calling run() method directly.

Categories

Resources