I have a simple HTML server program that listens on port 8000 for a request. I want to be able to request an HTML file from the server program and send the requested HTML back to the browser. Currently the server receives the request and parses the requested filename from the request, and will even print the contents of the html file to the console. However, when I try to print the HTML file contents to the connection's socket (back to the browser) nothing happens; the browser just continues loading.
My server class is relatively simple and just creates instances of this runnable class, RequestHandler, for each connection:
package server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class RequestHandler extends Thread {
Object block;
ServerSocket serverSocket;
BufferedReader socketReader;
PrintWriter socketWriter;
public RequestHandler(Object block, ServerSocket serverSocket){
this.block = block;
this.serverSocket = serverSocket;
}
#Override
public void run() {
try{
System.out.println("Waiting for request...");
Socket clientSocket = serverSocket.accept();
System.out.println("Connection made.");
synchronized(block){
System.out.print("Notifying server thread...");
block.notify();
System.out.println("...done");
System.out.println();
}
socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);
String input;
while((input = socketReader.readLine()) != null){
// System.out.println(input);
if(input.startsWith("GET")){
getResource(input);
}
}
}catch(IOException e){
System.out.println("IOException!");
e.printStackTrace();
}
}
public void getResource(String getRequest){
String[] parts = getRequest.split("\\s+");
String filename = parts[1].substring(1);
System.out.println(filename);
File resource = new File(filename);
sendResponse(resource);
}
public void sendResponse(File resource){
System.out.println(resource.getAbsolutePath());
Scanner fileReader;
try {
fileReader = new Scanner(resource);
while(fileReader.hasNext()){
String line = fileReader.nextLine();
System.out.println(line);
socketWriter.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
}
}
What should you always do when you're done writing to or reading from a stream? (I know the answer to your question, but I'm asking this question because you labeled your question as "homework")
Related
So there this problem that has been giving me headaches for days now.I am making a multi-user chat application.My design is as follows:
1.There is a login window.
2.As soon as the details are entered, the client-side chat window opens.
3.Now the user starts typing.
4.As soon as he hits enter or clicks on the send button,the message is sent to the server.
5.The server sends it to all clients, including the one that send it the original message.
The problem:I am unable to receive any messages from the server to the client.
Here is my server class:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server implements Runnable {
static InetAddress address;
static ArrayList<Integer> clients=new ArrayList<Integer>();
static ArrayList<Socket> socs=new ArrayList<>();
static String message="";
static DataOutputStream toClient;
static ServerSocket socket;
static Socket socketNew;
static boolean running=false;
public static void main(String[] args) throws IOException
{
socket=new ServerSocket(8000);
System.out.println("Server started on port 8000");
running=true;
while(true)
{
socketNew=socket.accept();
socs.add(socketNew);
address=socketNew.getInetAddress();
System.out.println("connected to client at address: "+address);
Server server=new Server();
new Thread(server).start();
}
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socketNew.getInputStream()));
String message;
PrintWriter out;
while ((message = br.readLine()) != null) {
System.out.println(message);
for (Socket s : socs) // sending the above msg. to all clients
{
out = new PrintWriter(s.getOutputStream(), true);
out.write(message);
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
And here is the receive_message function in the client class.Note that this method,I've run on a separate thread that starts as soon as the user logs-in.
public void receive_data()
{while(true)
{
try {
BufferedReader in;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(in.readLine()!=null)
{
System.out.println(in.readLine());
console(in.readLine());
}
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
Any suggestions?Thanks for your time. :-)
You are writing messages without a line ending, while your client is waiting for a line ending character in the readLine loop. By placing out.write('\n') in your server send loop, it will also send a newline character.
Example:
for (Socket s : socs) {
out = new PrintWriter(s.getOutputStream(), true);
out.write(message);
out.write('\n'); // added this line
out.flush();
}
Here's my code:
SERVER:
package server;
public class Main {
public static void main(String args[]) {
new EchoServer(9000);
}
}
+
package server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
private ServerSocket server;
public EchoServer(int port) {
try {
server = new ServerSocket(port);
while (true) {
Socket socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(in.readLine() + " | MOD");
socket.close();
}
} catch(Exception err) {
err.printStackTrace();
}
}
}
CLIENT:
package client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Main {
public static void main(String args[]) {
try {
while (true) {
Socket socket = new Socket("localhost", 9000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
out.println(input.readLine());
System.out.println(in.readLine());
socket.close();
}
} catch (Exception err) {
System.out.println(err);
}
}
}
It works all as it should, except that I want when the server sends the "message" + " | MOD" to the client, I want the server to send that to all clients, how can I do that?
I am new to Java, but not to coding so please help me if I've done some wrong stuff that can be done easier or better.
Please help.
Thanks alot.
What you can do is save the client sockets in an array, and then use a for loop to send to each socket.
First, declare your clientSocket array; note that 5 is just an arbitrary size used for testing. Also, declare a counter int.
public Socket clientSocket[] = new Socket[5];
public int intLastSocket = 0;
// this should be placed where you're waiting to accept connections
while (true) {
printTCP("Ready to accept welcome socket");
clientSocket[intLastSocket] = welcomeSocket.accept();
intLastSocket++;
}
// on the server, call this to send. s is a reference to the server object
public void sendToAllTCP(TCPServer s, String message) {
for (Socket z : s.clientSocket) {
if (z != null) {
PrintStream outToClient = null;
try {
outToClient = new PrintStream(z.getOutputStream());
outToClient.println(message);
} catch (IOException e) {
TCPServer.printTCP("Caught an IO exception trying "
+ "to send to TCP connections");
e.printStackTrace();
}
}
}
}
IN YOUR CODE:
package com.murplyx.server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
private ServerSocket server;
// use the clientSocket Array to save each new connection
public Socket clientSocket[] = new Socket[5];
public EchoServer(int port) {
try {
server = new ServerSocket(port);
// this should be placed where you're waiting to accept connections
while (true) {
System.out.println("Ready to accept welcome socket");
clientSocket[intLastSocket] = server.accept();
intLastSocket++;
//send your message here, note that putting
//it here will send it each time u add a new connection
sendToAllTCP(/*the message you want to send */);
}
} catch(Exception err) {
err.printStackTrace();
}
}
public void sendToAllTCP(String message) {
// this is an enchanced for loop, i don't know if it's in other languages
// but in java it's supposed to let you loop through
//each object in any iterable list
// such as array, arraylist, linkedlist, etc
for (Socket z : clientSocket) {
if (z != null) {
//basically this chunk of code declares output and input streams
//for each socket in your array of saved sockets
PrintStream outToClient = null;
try {
outToClient = new PrintStream(z.getOutputStream());
outToClient.println(message);
} catch (IOException e) {
System.out.println("Caught an IO exception trying "
+ "to send to TCP connections");
e.printStackTrace();
}
}
}
}
}
Depending on when you want to send your message, you can use the console and sys.in to send it. For example, if you read a line from sys.in and it .equals("sendMsg"), then you can call sendToAllTCP(yourmessage)
You should take a look at multiThreaded chat Server. Each client wich connects gets it's own thread.
Here is the perfect answer to your question:
multithread client-server chat, using sockets
Good luck mate!
I am trying to implement FTP protocol using socket programing in java. I am using the ObjectOutputStream to write the data requested to the socket in the server side but i am getting the following error on the console window..
Software caused connection abort: socket write error
Here is the implementation of my program
Server side:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class FTPServer {
public static void main(String[] args) {
try {
#SuppressWarnings("resource")
ServerSocket ss = new ServerSocket(4550);
while(true) {
Socket socket = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
FileInstance file = new FileInstance();
System.out.println(file.srcDir = br.readLine());
System.out.println(file.destDir = br.readLine());
System.out.println(file.filename = file.srcDir.substring(file.srcDir.lastIndexOf("/") + 1));
File f = new File(file.srcDir);
byte[] bytes = new byte[(int)f.length()];
FileInputStream fis = new FileInputStream(f);
fis.read(bytes);
file.FILE_SIZE = bytes.length;
file.fileData = bytes;
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(file);
System.out.println("Success");
oos.close();
fis.close();
br.close();
}
} catch(IOException e) {
System.out.println(e.getMessage());
}
}
}
Client Side:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class FTPClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 4550);
BufferedReader sbr = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the path of requested file");
String path = sbr.readLine();
System.out.println(path);
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Enter Destination");
path = path + "\n" + sbr.readLine();
System.out.println(path);
pw.write(path);
pw.close();
sbr.close();
// receive file
ObjectInputStream ois= new ObjectInputStream(socket.getInputStream());
FileInstance file = (FileInstance)ois.readObject();
ois.close();
if(!new File(file.destDir).exists())
new File(file.destDir).mkdir();
File nfile = new File(file.destDir + "/" + file.filename);
FileOutputStream fos = new FileOutputStream(nfile);
fos.write(file.fileData);
fos.close();
socket.close();
System.out.println("Success");
} catch(IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
this is the FileInstance class......
import java.io.Serializable;
public class FileInstance implements Serializable {
private static final long serialVersionUID = 1L;
public String destDir;
public String srcDir;
public String filename;
public long FILE_SIZE;
public byte[] fileData;
public String status;
}
You have two problems in FTPClient
You are closing the socket prematurely. At line 22 pw.close() needs to be pw.flush()
Even after you fix the first issue the server will hang. You need to add a newline to the end of the path string you send so the server, using readLine(), can read entire lines; otherwise it waits forever for a complete line that never arrives.
This was trivial to debug in Eclipse. If you want to be a good developer, debugging skills are crucial. Set more than one breakpoint and see what happens. Experiment. Play. Learn.
i am creating a LAN game that accepts strings and parses them from structured english and displays them on a grid. i have created the server and client and it works but im having some issues. when i send a string it doesnt appear on the other machine right away. for some reason the string is only sent to the other machine once the other machine sends something over. i dont know why this happens. Could you please help me find out why it doesnt send straight away. Thanks
Server Code:
import java.awt.Point;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class studentServer{
static ServerSocket serverSocket;
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
Console console = new Console();
public ServerPlayergameMain gm;
public static void main(String args[]) throws Exception{
}
public void run(String commandMessage){
while(true){
try{
printWriter.println(commandMessage+"\n");
String input = bufferedReader.readLine();//reads the input from textfield
console.readLine("Client message: "+input);//Append to TextArea
}catch(Exception e){}
}
}
public void serverStartActionPerformed() {
System.out.println("Server has started!");
try{
serverSocket = new ServerSocket (8888); // socket for the server
socket = serverSocket.accept(); // waiting for socket to accept client
JOptionPane.showMessageDialog(null, "Your opponent has connected!", "Opponent Connection!", JOptionPane.INFORMATION_MESSAGE);
gm = new ServerPlayergameMain();
gm.setVisible(true);
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // reads line from input streamer
printWriter = new PrintWriter(socket.getOutputStream(),true);
}catch(IOException | HeadlessException e){
System.out.println("Server not running!"); //print message if server is not running
}
}
}
Client Code:
import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;
public class StudentClient {
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
Console console = new Console();
public ClientPlayergameMain gm;
public void Clients(String address) {
try{
socket=new Socket("localhost",8888);//Socket for client
//below line reads input from InputStreamReader
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//below line writes output to OutPutStream
printWriter=new PrintWriter(socket.getOutputStream(),true);
JOptionPane.showMessageDialog(null, "Connected to server successfully", "Success", JOptionPane.INFORMATION_MESSAGE);
gm = new ClientPlayergameMain();
gm.setVisible(true);
System.out.println("Connected");//debug code
}catch(Exception e){
JOptionPane.showMessageDialog(null, "No Connection to server", "Error", JOptionPane.ERROR_MESSAGE);
System.out.println("Not Connected");
}
}
public static void run(String commandMessage){
while(true){
try{
printWriter.println(commandMessage+"\n");
String input = bufferedReader.readLine();
System.out.println("From server:" +input);
}catch(Exception e) {}
}
}
}
The code works but i dont know why there is a condition for the other machine to send something.
Thanks for your time.
A lot of compilation problems are there in you code. Some of the classes and objects are missing to resolve.
Still I have tried it to figure out the issue.
It may be the reasons:
sending new line character \n in printWriter.println(commandMessage+"\n"); statement, just remove \n.
client and server both are writing first in printWriter.println(commandMessage+"\n"); statement, make it last in anyone class
Here is the code:
StudentServer.java:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class StudentServer {
static ServerSocket serverSocket;
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
public static void main(String args[]) throws Exception {
StudentServer studentServer = new StudentServer();
studentServer.serverStartActionPerformed();
studentServer.run("server");
}
public void run(String commandMessage) {
if (true) {
try {
printWriter.println(commandMessage);
String input = bufferedReader.readLine();// reads the input from textfield
System.out.println("Client message: " + input);// Append to TextArea
} catch (Exception e) {
}
}
}
public void serverStartActionPerformed() {
System.out.println("Server has started!");
try {
serverSocket = new ServerSocket(8888); // socket for the server
socket = serverSocket.accept(); // waiting for socket to accept client
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // reads
// line
// from
// input
// streamer
printWriter = new PrintWriter(socket.getOutputStream(), true);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Server not running!"); // print message if server is not running
}
}
}
StudentClient.java:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class StudentClient {
static Socket socket;
static PrintWriter printWriter;
static BufferedReader bufferedReader;
static Thread thread;
public void clients() {
try {
socket = new Socket("localhost", 8888);// Socket for client
// below line reads input from InputStreamReader
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// below line writes output to OutPutStream
printWriter = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Connected");// debug code
} catch (Exception e) {
System.out.println("Not Connected");
}
}
public void run(String commandMessage) {
if (true) {
try {
String input = bufferedReader.readLine();
System.out.println("From server:" + input);
printWriter.println(commandMessage);
} catch (Exception e) {
}
}
}
public static void main(String args[]) throws Exception {
StudentClient studentClient = new StudentClient();
studentClient.clients();
studentClient.run("client");
}
}
Have you tried printWriter.flush() after each write/print?
There are quite a few little problems, as Braj points out. The main one is in this sequence on your server side:
serverSocket = new ServerSocket (8888); // socket for the server
socket = serverSocket.accept(); // BLOCKS waiting for socket to accept client
// ..
printWriter = new PrintWriter(socket.getOutputStream(),true);
This means that printWriter, which you use to write to the client, doesn't even exist until after the server has listened for, blocked waiting on, and accepted a connection from the client.
If you want the connection to be opened for reading and writing without seeming to send anything from the client, send a handshake from the client. You could copy SMTP, and use HELO <myname>. That even tells the server who's calling.
Update after further reading:
I've always done like you have, and used the implicit connect that happens when you use getOutputStream() on the client side. However, Socket does allow you to connect an existing socket manually, using Socket#connect(). Try that, maybe it will work better than a handshake, for you.
I'm new to java socket programming, this program allows TCP server to have a multi-thread that can run concurrently. I try to send the txt file from one client(has another client that will sent file at the same time) to the server side and ask server to send "ok" status message back to client side. But it seems that the server can't receive any file from the client and the strange thing is if i delete the receiveFile() method in my client class, the server is able to recieve the file from client. Can somebody help me?
Server.class
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;
import java.net.SocketException;
public class ConcurrentServer {
public static void main(String args[]) throws IOException
{
int portNumber = 20020;
ServerSocket serverSocket = new ServerSocket(portNumber);
while ( true ) {
new ServerConnection(serverSocket.accept()).start();
}
}
}
class ServerConnection extends Thread
{
Socket clientSocket;
ServerConnection (Socket clientSocket) throws SocketException
{
this.clientSocket = clientSocket;
setPriority(NORM_PRIORITY - 1);
}
public void run()
{
try{
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
OutputStream outToClient = clientSocket.getOutputStream();
PrintWriter printOutPut = new PrintWriter(outToClient,true);
while(inFromClient.ready())
{
String request = inFromClient.readLine();
System.out.println(request);
System.out.println("test");
}
printOutPut.write("HTTP/1.1 200 OK\nConnection: close\n\n");
printOutPut.write("<b> Hello sends from Server");
printOutPut.flush();
printOutPut.close();
clientSocket.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Client.class
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SmallFileClient {
static String file="test.txt";
static PrintWriter outToServer;
static Socket socket;
public static void main(String[] args) throws IOException
{
final int PORT=20020;
String serverHostname = new String("127.0.0.1");
socket = new Socket(serverHostname, PORT);
outToServer = new PrintWriter(socket.getOutputStream(),true);
sendFile();
receiveFile();
outToServer.flush();
outToServer.close();
socket.close();
}
//read file and send file to server
public static void sendFile() throws IOException
{
BufferedReader br=new BufferedReader(new FileReader(file));
try
{
String line = br.readLine();
while(line!=null)
{
//send line to server
outToServer.write(line);
line=br.readLine();
}
}catch (Exception e){System.out.println("!!!!");}
br.close();
}
//get reply from server and print it out
public static void receiveFile() throws IOException
{
BufferedReader brComingFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try
{
String inline = brComingFromServer.readLine();
while(inline!=null)
{
System.out.println(inline);
inline = brComingFromServer.readLine();
}
}catch (Exception e){}
}
}
Get rid of the ready() test. Change it to:
while ((line = in.readLine()) != null)
{
// ...
}
readLine() will block until data is available. At present you are stopping the read loop as soon as there isn't data available to be read without blocking. In other words you are assuming that `!ready()! means end of stream. It doesn't: see the Javadoc.