I am writing a Client application which sends requests to the server. I have started my server from Windows, using StartServer batch file. Now, the requests that server expects are HTTP requests. If I open up a request from my web browser, the server sees it and responds to it, but I am having a bad time trying to send the requests from Java.
For example, command "http://localhost/?command=reg&person=sophie" works fine when started from a browser, but from Java it returns a FileNotFound exception.
Here is the code:
public class Client {
private Socket clientSocket;
private final int PORT_NUMBER;
private final String HOST_NAME;
private PrintWriter writer;
private BufferedReader reader;
public Client(int PORT_NUMBER, String HOST_NAME){
this.PORT_NUMBER = PORT_NUMBER;
this.HOST_NAME = HOST_NAME;
try {
clientSocket = new Socket(HOST_NAME, PORT_NUMBER);
writer = new PrintWriter(clientSocket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("Error creating socket!");
}
}
public void registerPerson(String personName) throws IOException{
URL url = new URL("http://localhost/?command=reg&person=sophie");
InputStream in = new BufferedInputStream(url.openStream());
Scanner sc = new Scanner(in);
sc.nextLine();
}
This line, InputStream in = new BufferedInputStream(url.openStream());, returns a FileNotFound exception. Any suggestions on that?
Have you tried using 127.0.0.1 instead of localhost. The problem might arise because java does not recognize your loopback address (ie localhost).
Have you tried accessing the URL differently?
URL fileURL = new URL("http://localhost/?command=reg&person=sophie");
URLConnection connection = fileURL.openConnection();
connection.connect();
inputStream = new java.io.BufferedInputStream(connection.getInputStream());
Also using the IP address instead of localhost is a good idea, as suggested in an another answer.
Related
Bare with me as it's been a while since I've been on here and I know there's format rules for questions. I have coded two java applications, both are pretty simple. One being a server and two being a client that connects to the server via socket. Now this works on my computer but when I have a buddy run on his computer it doesn't connect. I want the server to be able to run on my computer and anyone who has the client can connect.
The relevant code for the server:
public static void main(String[] args) throws IOException {
// write your code here
System.out.println("Server Running...");
int port = 1020, backlog = 5;
String ipAddress = "2552:548:41aa:c3f0:563c:hgj9:8ca2:b3aa";
ServerSocket serverSocket = new ServerSocket(port, backlog, InetAddress.getByName(ipAddress));
Server server = new Server(serverSocket);
server.startServer();
}
The relevant code for the client:
public class Client{
public String username;
private Socket socket = new Socket("2552:548:41aa:c3f0:563c:hgj9:8ca2:b3aa", 1020);
public BufferedReader bufferedReader;
public BufferedWriter bufferedWriter;
public ChatController chatController;
public Client(String username) throws IOException {
try {
this.username = username;
this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write(username);
bufferedWriter.newLine();
bufferedWriter.flush();
listenForMessage();
} catch (IOException e) {
closeEverything(socket, bufferedReader, bufferedWriter);
}
}
Like I said, this works on my computer but the not when client is on a different computer. My thoughts are that the issue is on the client side, possibly not using an open port? Thank you in advance and let me know if I need to edit if it's not a proper question format.
Here I am creating a thread to check for a server response every 2 seconds, the issue is that the client.monitorResponse() is a readLine() method and will not continue until a response is received.
client = new ClientObject("localhost");
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
String response = null;
if(!(response = client.monitorResponse()).isEmpty()) {
System.out.println("Response: " + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 2000, 2000);
I am sending the response via the Server like so (where client is a established Socket):
public SocketObject(Socket client, int numberOfClients) throws Exception {
socket = client; // the .accept() socket is passed through
// this is because I assign them ID's for later use (I hold an ArrayList of sockets)
this.clientId = numberOfClients;
// both these are static to the class
outputStream = new PrintWriter(client.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
}
public void sendResponse(String response) {
outputStream.println(response);
}
I am then picking the response up via the client Socket that has connected to the server:
public ClientObject(String hostname) throws IOException {
// socket is static to this class
socket = new Socket(hostname, 4444);
System.out.println("Connected to " + hostname + " on port 4444...");
// both static to this class
outputStream = new PrintWriter(socket.getOutputStream(), true);
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Successfully started a stream on " + hostname);
this.hostname = hostname;
}
public String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
return inputStream.readLine();
}
The debug console only displays the Listening for a response... output once which is telling me that it doesn't get past the inputStream.readLine() method in-side the Thread. Is there anyway I can add a timeout on the BufferedReader? I have tried multiple solutions like adding a .setSoTimeout() to the socket before creating the BufferedReader but all that did was close the connection/socket after the specified time.
Any help would be appreciated.
You should use a non-blocking (NIO) request and read chunks looking for newlines in-between. Typically in Java you just have to look for the NIO version of the Stream class you are using and use it to check every N seconds for new content. In your case with minimal modifications you can use the less fancy and efficient method of blocking calls with BufferedReader.ready() to prevent blocking:
String partialLine="";
public static String monitorResponse() throws Exception {
System.out.println("Listening for a response...");
int nextByte;
String nextChar;
while (inputStream.ready()) {
nextByte = inputStream.read();
nextChar = Character.toString ((char) nextByte);
partialLine += nextChar;
if ("\n".equals(nextChar)) {
String line = partialLine;
partialLine = "";
return line.replace("\r\n", "");
}
}
return "";
}
Check out http://tutorials.jenkov.com/java-nio/nio-vs-io.html for more info.
Is there anyway I can add a timeout on the BufferedReader?
No, but you can set a timeout on the Socket, with Socket.setSoTimeout().
I have tried multiple solutions like adding a .setSoTimeout() to the socket before creating the BufferedReader but all that did was close the connection/socket after the specified time.
No it doesn't close the socket. It throws SocketTimeoutException, which you should catch and handle as pertinent. If the socket is being closed, you're closing it. Solution: don't.
I have written a TCP Client program which calls the properties file and takes the values from there. When I run the TCPClient for the first time, it runs properly and sends all the data values of server.properties file to the server, but as soon as I try to add one more data "data4" to server.properties file my project gets a "x" mark and the changes made in server.properties file don't reflect and I get Error: cannot find or load class TCPClient.
I tried to create a new project, still the same, the changes made to properties file do not reflect. Can someone kindly help me on this. Thanks in advance
public class TCPClient {
private static Socket socket;
public String getPropertyValues() throws IOException{
String result="";
Properties prop = new Properties();
String propFileName = "server.properties";
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
prop.load(inputStream);
try
{
String host = prop.getProperty("host");
System.out.println(host);
int port = Integer.parseInt(prop.getProperty("port"));
System.out.println(port);
String data = prop.getProperty("data");
System.out.println(data);
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);
String sendMessage = data;
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent to the server : "+sendMessage);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from the server : " +message);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
return result;
}
public static void main(String[] args) throws IOException{
TCPClient properties = new TCPClient();
properties.getPropertyValues();
}
}
I have a properties file by name server.properties
data = data1
data2
data3
port = 3035
host = localhost
When ever I make change to the data field of this properties file and save, the project turns with a "x" mark and when I try to run the TCPClient program using Run as-->JavaApplication, I get the pop up as
Errors exist in required project
Test
Proceed with Launch?
How can I change this code:
public class bingoMachineControl {
void sendCommand(String command) throws IOException {
String ipaddress = "192.168.0.2";
Socket commandSocket = null;
// PrintWriter out = null;
BufferedWriter out = null;
BufferedReader in = null;
BufferedWriter outToDetailFile = null;
FileWriter fstream = null;
String version = "";
int numberOfBallsInGame;
int ledCycleState = 1;
commandSocket = new Socket(ipaddress, 7420);
// out = new PrintWriter(commandSocket.getOutputStream(), true);
out = new BufferedWriter(new OutputStreamWriter(commandSocket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(commandSocket.getInputStream()));
out.write("c");out.flush();
out.write(command);out.flush();
String message = in.readLine();
out.close();
in.close();
commandSocket.close();
}
}
To be able to connect to socket on event (let's say button click), send a message to port on event and then close the socket connection also on event.
Thank you
If you want to keep up the connection, you'll have to make the Socket a class variable.
Then you can access it from each method in that class.
Open the socket when you instantiate the class and close when you are done with sending / receiving.
Mind that you might need to introduce a Thread for keeping the EDT clean from Network communication.
I'm trying to get a simple multithreaded proxy to work in Java. However I don't manage to get the webpage show up in my browser, after the first GET request and the response from the webpage, the program is just stuck (as you can see from my code, I'm printing everything i get on the stdout for debugging, and there I see the sourcecode of the webpage, however after printing out "After Client Write", nothing happens (no exception, just nothing...)).
import java.net.*;
import java.util.*;
import java.io.*;
public class Proxy
{
public static void main(String[] args)
{
try
{
ServerSocket listensocket = new ServerSocket(Integer.valueOf(args[0]));
while(true)
{
System.out.println("wait");
Socket acceptsocket = listensocket.accept(); // blocking call until it receives a connection
myThread thr = new myThread(acceptsocket);
thr.start();
}
}
catch(IOException e)
{
System.err.println(">>>>" + e.getMessage() );
e.printStackTrace();
}
}
static class myThread extends Thread
{
Socket acceptsocket;
int host, port;
String url;
myThread(Socket acceptsocket)
{
this.acceptsocket=acceptsocket;
}
public void run() {
try
{
System.out.println("hello");
Socket client = acceptsocket;
//client.setSoTimeout(100);
InputStream clientIn = client.getInputStream();
//BufferedInputStream clientIn=new BufferedInputStream(clientis);
OutputStream clientOut = client.getOutputStream();
System.out.println("hello");
String clientRequest = readStuffFromClient(clientIn); // parses the host and what else you need
System.out.print("Client request: -----\n"+clientRequest);
Socket server;
server = new Socket("xxxxxxxxxxxxx" , 80);
InputStream serverIn = server.getInputStream();
//BufferedInputStream serverIn=new BufferedInputStream(serveris);
OutputStream serverOut = server.getOutputStream();
serverOut.write(clientRequest.getBytes());
serverOut.flush();
String serverResponse = readStuffFromClient(serverIn);
System.out.print("Server Response: -----\n"+serverResponse);
clientOut.write(serverResponse.getBytes());
clientOut.flush();
System.out.println("After Client Write");
clientIn.close();
clientOut.close();
serverIn.close();
serverOut.close();
server.close();
client.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
private String readStuffFromClient(InputStream clientdata)
{
ByteArrayOutputStream response = new ByteArrayOutputStream();
StringBuffer request=new StringBuffer(8192);
int i, httpstart,n=-1 ;
byte[] buffer = new byte[8192];
System.out.println("beforetry");
try
{
while((n = clientdata.read(buffer))!=-1)
{
System.out.println("before");
response.write(buffer,0,n);
//response.flush();
}
request=new StringBuffer(response.toString());
/*System.out.println("new:"+n+" "+ request.toString());
System.out.println("End client data");*/
}
catch (Exception e)
{
System.out.println("here");
System.out.println(e);
e.printStackTrace();
i = -1;
}
System.out.println("End manipulation method");
return request.toString();
}
}
}
(this is a stripped down not working example of my program, from the comments one can see I already tried to use BufferedInputStream). In general, this program is very unresponsive even for the first GET request from the browser. When I only read the clientdata once (not in a loop), I get a little bit further, e.g. get more GET/Response pairs, but at some point the program still gets stuck.
Somehow I think either I've a real trivial error I just don't manage to see, or the program should work, but simply doesn't for no real reason.
Any help is appreciated, thanks in advance!
You need two threads: one to read from the client and write to the server, and one to do the opposite, for each accepted socket. There is a further subtlety: when you read EOS from one direction, shutdown the opposite socket for output, and then if the input socket for that thread is already shutdown for output, close both sockets. In both cases exit the thread that read the EOS.
Try getting first the OutputStream and then the InputStream!
InputStream clientIn = client.getInputStream();
OutputStream clientOut = client.getOutputStream();
change it to:
OutputStream clientOut = client.getOutputStream();
InputStream clientIn = client.getInputStream();
This will make it work:
It will check if there is more data available to read
Still, it's important that you use BufferedIS because I think ByteArrayIS doesn't implement available method.
BufferedInputStream bis = new BufferedInputStream(clientdata);
System.out.println("beforetry");
try {
while(bis.available() > 0){
n = bis.read(buffer);
response.write(buffer, 0, n);
}