I've been working on simple http server in java. When I try to send some http request via google
browser "line" variable should have request string but it has junk characters.
Do you have any idea what is causing the problem?
Code is from this tutorial: https://www.youtube.com/watch?v=FqufxoA4m70&t=2061s&ab_channel=BloomInstituteofTechnology
Here is part of code where you can find this problem.
package com.company;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Main
{
public static void main(String[] args) throws Exception
{
try( ServerSocket socketServer = new ServerSocket(8080))
{
System.out.println("Server created");
while (true)
{
try (Socket client = socketServer.accept())
{
System.out.println("Client connected: " + client.toString());
InputStreamReader isr = new InputStreamReader(client.getInputStream());
BufferedReader br = new BufferedReader(isr);
StringBuilder request = new StringBuilder();
String line;
line = br.readLine();
while(!line.isBlank())
{
request.append(line);
line = br.readLine();
}
}
}
}
}
I don't know what you're actually doing with your browser. What are you typing in the URL bar? If you are trying to use https instead of http it will not work. Maybe "google browser" is tricking you and doing stuff behind your back... not exactly sending simple HTTP gets.
This works. It's not perfect but at least all IO streams are properly closed and a dummy response is sent to the client (which otherwise will remain hanging).
Try it by typing in your browser http://localhost:8080/some-random-url.
I cannot try with chrome as I don't use it, but this works using Firefox. As a rule, i would test stuff like this with curl and not with a browser - you have more control while testing simple stuff.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws Exception {
try (ServerSocket socketServer = new ServerSocket(8080)) {
System.out.println("Server created");
while (true) {
try (Socket client = socketServer.accept()) {
System.out.println("Client connected: " + client.toString());
try (final InputStream is = client.getInputStream();
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
final OutputStream os = client.getOutputStream()) {
final StringBuilder request = new StringBuilder();
String line;
while (!(line = br.readLine()).isBlank()) {
request.append(line).append("\n");
}
System.out.println("+++++++++++++++++++++++ REQUEST ");
System.out.println(request);
String response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Connection: closed\r\n" +
"\r\n" +
"Hello there!\r\n";
os.write(response.getBytes(StandardCharsets.UTF_8));
os.flush();
System.out.println("----------------------- RESPONSE ");
System.out.println(response);
}
}
}
}
}
}
Random remark: don't implement an HTTP server on your own. Just do it to understand how it works.
Related
I am learning Java and I'm writing an example client - server application.
The sokcket connection is fine, everything works well until the second message from the client app. It does not reach the server. If I start another client it also succeed at the first message, and fails at the second.
Anyone has an idea? Thanks in advance!
Server code:
package networking;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static Socket socket;
public static void main(String[] args) {
try {
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
//Server is running always. This is done using this while(true) loop
while (true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
String returnMessage = incomingMessage;
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
bw.flush();
System.out.println("))) " + returnMessage);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (Exception e) {
}
}
}
}
And the client
package networking;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
private static Socket socket;
public static void main(String args[]) {
try {
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = "";
/*
while(!message.equals("q")) {
System.out.print("Message: ");
message = console.readLine();
bw.write(message + "\n");
bw.flush();
System.out.println("))) " + message);
//Get the return message from the server
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
}
*/
for (int i = 0; i < 10; i++) {
bw.write(i + "\n");
bw.flush();
System.out.println("))) " + i);
String incomingMessage = br.readLine();
System.out.println("((( " + incomingMessage);
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
//Closing the socket
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Your while is misplaced in your server code, and in fact you need 2 while loops:
one for accepting new clients
one for manage several messages by client
In pseudo code it gives you:
while (true):
accept new client
while (client connected):
read message from client
write back message to client
close client socket
If you want to use threads, then it's the inner while loop task which you have to delegate to a new thread.
Note: accept is blocking until a new client comes. That why you could send only one message by client.
Your server is not set up to handle this. You are reading one line, then discarding the connection for the GC, without closing it. The server, reading one line, then ignores all other lines and starts listening for the next connection.
Also, consider using threads.
I am currently learning Java and am playing around with socket programming.
My goal is to implement request-response communication like HTTP. I can get one way communication from the client to the server. But when I program the client to listen for a response it causes the server to not print out the request.
I've googled the issue and most posts mention using the flush() method, which I have tried. Anyone have any thoughts?
Here is the client code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
class Client {
public static void main(String args[]) throws IOException {
// Get the port number from the first command line argument
int port_number;
if(args.length == 0) {
port_number = 80;
} else {
port_number = Integer.parseInt(args[0]);
}
try (
// Create a socket
Socket socket = new Socket("localhost", port_number);
// Input reader
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
// Output writer
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
) {
System.out.println("Sending request");
out.print("Foo");
out.flush();
System.out.println("Sending Complete");
// If this next section is commented out then the server prints the message
StringBuilder message = new StringBuilder();
int data;
while((data = in.read()) != -1) {
message.append((char) data);
}
System.out.print(message);
}
}
}
and here is my server code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String args[]) throws IOException {
// Get the port number from the first command line argument
int portNumber = Integer.parseInt(args[0]);
System.out.println("Listening on port " + portNumber);
ServerSocket serverSocket = new ServerSocket(portNumber);
while (true) {
try (
Socket socket = serverSocket.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
){
StringBuilder message = new StringBuilder();
int data;
while((data = in.read()) != -1) {
message.append((char) data);
}
System.out.println(message);
out.print("Bar");
}
}
}
}
This is because your sever currently loop until read() returns -1 which never happens in your case so he never reaches the part of the code where he is supposed to send Bar, you need a specific marker to indicate the end of your message so for example here you can send data line by line, for this proceed as next:
Client side:
System.out.println("Sending request");
// Send a line to the server
out.println("Foo");
out.flush();
System.out.println("Sending Complete");
// Read a line sent by the server
System.out.print(in.readLine());
Output:
Sending request
Sending Complete
Bar
Server side:
// Print the line sent by the client
System.out.println(in.readLine());
// Send a message to the client
out.println("Bar");
Output:
Listening on port 9999
Foo
Good evening, i got this server here,
httpServer
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicInteger;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class httpServer {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/test", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
//NimServer nimserver = new NimServer(32778);
//nimserver.serve();
}
static class MyHandler implements HttpHandler {
AtomicInteger atomicInteger = new AtomicInteger(0);
int theValue = atomicInteger.get();
#Override
public void handle(final HttpExchange t) throws IOException {
final String response;
final String requestMethod = t.getRequestMethod();
if ("GET".equals(requestMethod)) {
response = String.format("Besuche: %d%n", atomicInteger.addAndGet(1));
}
else if ("POST".equals(requestMethod)) {
atomicInteger.set(0);
response = "Reset to 0";
}
else {
throw new IOException("Unsupported method");
}
t.sendResponseHeaders(200, response.length());
final OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
and this Client here
httpClient
import java.net.*;
import java.io.*;
public class httpClient {
static int clientno = 0;
public static void main(String[] args) throws Exception {
System.out.println(clientno);
URL test = new URL("http://localhost:8000/test");
HttpURLConnection connect = (HttpURLConnection) test.openConnection();
connect.setRequestMethod("POST");
BufferedReader in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Now i want to send the int clientno from the client to the server and the server should count it up like ++ and send it back to the client. I read alot about Dataoutputstream but there are always sockets included. Is it possible to do it without sockets?
On the server side you in the handler for "POST" you have to invoke t.getRequestBody() - this will give you client input. Either using BufferedReader (if text based - Integer.valueOf(stream.readLine())) or DataInputStream (if binary based - stream.readInt()) you can read the number. Similarly by t.getResponseBody() you get the output to client and write the number in similar way.
For the client the HttpURLConnection has getInputStream() and getOutputStream() to which you need to write clientNumber similarly how you do in server.
I need to read a "bdd.txt" file placed on a Virtual Machine on my computer. I made a client/server system in Java. My Server.java is on my VM (Ubuntu) with a "database" (the bdd.txt file in the same folder), and my Client.java is on my Windows 7.
So far I have split my code into 2 different files (Server/Client) and I made the connexion between my Windows 7 and my VMware Player's Ubuntu. When I start my server on my VM, it listens on a port number x, then I go back on my Windows and run my client. It asks to make the connexion and then, back on my VM, I print a message "The connexion is made" and my app is running. So now I can communicate between them. I have just used socket = new Socket("my VM ip address",portNumber); and it works. But now, I have no idea how to adapt my code to reach my bdd.txt file I moved on my VM.
How can I now read the bdd.txt file, to have access to the pin codes ?
Why is my new Client() never called in my program?
Here is Client.java :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
int pinSize = 0;
//set up server communication
Socket clientSocket = new Socket(InetAddress.getLocalHost(),1234);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
Scanner scanner = new Scanner(System.in);
System.out.println("Enter pin : ");
String password = scanner.next();
pinSize = password.length();
//send PIN to server
out.println(password);
if (pinSize != 4) {
System.out.println("Pin must be 4 digits");
} else {
System.out.println("Checking...");
}
out.flush();
//get response from server
String response = in.readLine();
System.out.println(response);
in.close();
out.close();
clientSocket.close();
}
}
Here is Server.java (in the same folder as bdd.txt):
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static ServerSocket server;
public static void main(String[] args) throws Exception {
server = new ServerSocket(1234);
Socket socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
//Listen for client requests:
String request;
while ((request = in.readLine()) != null) {
//check PIN, send result
boolean pinCorrect = checkPin(request);
out.println(pinCorrect ? "yes" : "no");
out.flush();
}
out.close();
in.close();
socket.close();
}
/**
* Check if PIN is in bdd.txt
* #throws IOException
*/
private static boolean checkPin(String pin) throws IOException {
boolean result = false;
File file = new File("bdd.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line;
while ((line = in.readLine()) != null) {
result |= (line.equals(pin));
}
in.close();
return result;
}
}
There's a lot of irrelevant stuff in you question, it's hard to see how your program works.
Here's what should happen:
Client side:
User inputs a number
Client sends user's number to server
Client receives response from server, and displays it
Server side:
Server listens for client connection
Server receives number from client
Server checks number against file bbd.txt
If number exists in file, return yes else return no
I have written some simple code to show you, excluding UI stuff:
Client.java:
public static void main(String[] args) {
//set up server communication
Socket clientSocket = new Socket("ip.address",1234);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
//send PIN to server
out.println("9.8.7.6");
out.flush;
//get response from server
String response = in.readLine();
System.out.println(response);
in.close();
out.close();
clientSocket.close();
}
Server.java:
public static void main(String[] args) throws Exception {
//Set up client communication
ServerSocket server = new ServerSocket(1234);
Socket socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
//Listen for client requests:
String request;
while ((request = in.readLine()) != null) {
//check PIN, send result
boolean pinCorrect = checkPin(request);
out.println(pinCorrect ? "yes" : "no");
out.flush();
}
out.close();
in.close();
socket.close();
}
/**
* Check if PIN is in bdd.txt
*/
private static boolean checkPin(String pin) {
boolean result = false;
File file = new File("bdd.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line;
while ((line = in.readLine()) != null) {
result |= (line.equals(pin));
}
in.close();
return result;
}
I'm trying to make a simple http client server using java. It will show the client's request as well as the server's response. For example server will send back
HTTP/1.0 200 OK
Connection: Close. etc.
Previously i had a echo client server. Now I've turned my echo server to act as a http server. I've tried Goggling about how to implement the head and get with the client but i noticed usually all of the example used apache framework. Is there a way to implement these method without apache framework.
My echo client which i'm trying to convert into a http client:
import java.io.*;
import java.net.*;
public class Ec1
{
public static void main(String[] args)
{
try
{
Socket s = new Socket("127.0.0.1", 80);
BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter w = new PrintWriter(s.getOutputStream(), true);
BufferedReader con = new BufferedReader(new InputStreamReader(System.in));
String line;
do
{
line = r.readLine();
if ( line != null )
System.out.println(line);
line = con.readLine();
w.println(line);
}
while ( !line.trim().equals("bye") );
}
catch (Exception err)
{
System.err.println(err);
}
}
}
My Http server:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Echo
{
protected void start() {
ServerSocket s;
System.out.println("Webserver starting up on port 80");
try {
// create the main server socket
s = new ServerSocket(80);
} catch (Exception e) {
System.out.println("Error: " + e);
return;
}
Socket clientSocket = null;
System.out.println ("Waiting for connection.....");
try {
clientSocket = s.accept();
System.out.println("Connection, sending data.");
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String str = ".";
while (!str.equals(""))
str = in.readLine();
out.println("HTTP/1.0 200 OK");
out.println("Content-Type: text/html");
out.println("Server: Bot");
out.println("");
out.println("<H1>Welcome to the Ultra Mini-WebServer</H2>");
out.flush();
clientSocket.close();
s.close();
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
public static void main(String args[]) {
WebServer ws = new WebServer();
ws.start();
}
}
Yes, there is, just interpret your request you're getting from the client.
From the following code (in HttpServer), parse:
String str = ".";
while (!str.equals("")) {
str = in.readLine();
if (str.startsWith("HEAD")) {
//Head execution here...
}
}
Etc...
Everybody uses some kind of library or framework for the client and/or the server side because HTTP is somewhat complex and there is no need to reinvent every wheel. However, it is quite possible to write your own implementation by starting directly from the RFCs for HTTP.