I'm writing a piece of software, and I'm under the restriction of not being able to use socket to connect to a java application using a ServerSocket.
I thought I'd try with an URL connection, since it's possible to define which port to connect to
e.g:
127.0.0.1:62666
I have my server app listening for connections and writing the input out to a jTextArea. When connecting to the server (127.0.0.1:62666) through a browser, it outputs:
GET / HTTP/1.1
GET /favicon.ico HTTP/1.1
I have another app for connecting to the ServerSocket through an URL connection:
try{
URL url = new URL("http://127.0.0.1:62666");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.connect();
PrintWriter writer = new PrintWriter(connection.getOutputStream());
writer.print("Hello");
System.out.println("should have worked");
writer.flush();
writer.close();
}catch(IOException e){
e.printStackTrace();
}
It prints out the "should have worked" message fyi, but it never writes anything to the jTextArea of the server. The code for the server app looks like this:
try{
ServerSocket serverSock = new ServerSocket(62666);
while(doRun){
Socket sock = serverSock.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter writer = new PrintWriter(sock.getOutputStream());
InfoReader.gui.writeToTextArea(reader.readLine() + " From IP: " + sock.getInetAddress() + "\n");
writer.println("Testing123");
writer.close();
reader.close();
}
}catch(IOException e){
e.printStackTrace();
}
Note: when connecting through the browser it displays the text "Testing123".
So I'm wondering how to do this the way I'm trying or perhaps read the URL that the ServerSocket was accessed through, so I could access it through a URL while passing it arguments (in the URL).
Hope this makes sense :)
Thanks,
Mike.
There is one very good example:
public class SimpleHTTPServer {
public static void main(String args[]) throws IOException {
ServerSocket server = new ServerSocket(8080);
while (true) {
try (Socket socket = server.accept()) {
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
}
}
}
}
Go to http://127.0.0.1:8080/ from browser and you'll get current date.
I can't figure out exactly what's up. There's something funny about that OutputStream. Add a
((HttpURLConnection) connection).getResponseCode();
somewhere after connect() and before close(), and you should see something different, if not what you expect.
Perhaps instead of trying to use HTTP as a hack, you should just go full HTTP. Use HTTP from the client like you already are, and set up an embedded HTTP server on the server. There are several to choose from out there that literally take just a few lines to get running: Grizzly, Simple Framework, or Jetty, for instance.
I think this is what you need to do if you want the client to send a message to the server using a URL connection:
public class Client
{
public Client()
{
try
{
url = new URL("http://127.0.0.1:62666");
URLConnection urlConnection = url.openConnection();
PrintWriter writer = new PrintWriter(urlConnection.getOutputStream());
writer.println("Hello World!");
writer.flush();
writer.close();
}catch(Exception e){e.printStackTrace();}
}
}
Now heres the server:
public class Server implements Runnable
{
public Server()
{
ServerSocket server = new Server(62666);
client = server.accept();
new Thread(this).start();
}
public void run()
{
try
{
String message;
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()))
while((message=reader.readLine())!=null)
{
System.out.println("Message from client: "+message);
}
}catch(Exception e)
{
System.out.println("Client disconnected");
}
}
Socket client;
}
writer.println("Hello");
You're not sending any newline. Also your 'should have worked' trace is in the wrong place. Should be after the flush().
Also you aren't reading the response.
Also the server is only going to display POST ... Or PUT ..., not the line you're sending. So this is never going to work unless you (a) make the server HTTP-conscious or (b) get rid of this insane restriction that you can't use a Socket. Why can't you use a Socket?
EDIT: my version of your code follows:
static class Server implements Runnable
{
public void run()
{
try
{
ServerSocket serverSock = new ServerSocket(62666);
for (;;)
{
Socket sock = serverSock.accept();
System.out.println("From IP: " + sock.getInetAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter writer = new PrintWriter(sock.getOutputStream());
String line;
while ((line = reader.readLine()) != null)
{
System.out.println("\t:" + line);
}
writer.println("Testing123");
writer.close();
reader.close();
System.out.println("Server exiting");
serverSock.close();
break;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
static class Client implements Runnable
{
public void run()
{
try
{
URL url = new URL("http://127.0.0.1:62666");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
// connection.setRequestMethod("POST");
connection.connect();
PrintWriter writer = new PrintWriter(connection.getOutputStream());
writer.println("Hello");
writer.flush();
System.out.println("flushed");
int responseCode = connection.getResponseCode();
writer.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
System.out.println("closed");
System.out.println("response code="+responseCode);
String line;
while ((line = reader.readLine()) != null)
System.out.println("client read "+line);
reader.close();
System.out.println("Client exiting");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
Thread t = new Thread(new Server());
t.setDaemon(true);
t.start();
new Client().run();
System.out.println("Main exiting");
}
Related
I'm trying to create a proxy server in Java that rotates proxies. What I mean is, I am creating a proxy server that passes on the request to another random proxy, gets the response from that random proxy and returns it back to the client.
Something like this:
Client Request -> My proxy server
My proxy server -> random proxy server
random proxy server -> My proxy server
My proxy server -> Client
I have 2 main classes handling this. The first class is called RunnableRequestLayer and it is responsible for reading the client's request, and sending the response back. The second class is RequestMaker which connects to a random proxy, and has a send() and receive() method which send/receive from the random proxy.
Here is the relevant code from both classes:
Class #1: RunnableRequestRelayer
public class RunnableRequestRelayer implements Runnable {
private Socket socket;
private final int maxTries = 5;
public RunnableRequestRelayer(Socket socket) {
this.socket = socket; //This socket is the serverSocket.accept() socket
}
#Override
public void run() {
System.out.println("Got a request!");
try(
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
){
RequestMaker rm = new RequestMaker();
int tries = 0;
while(tries++ < maxTries){
try{
rm.connect();
} catch(IOException e){
continue;
}
String inputLine;
//This while loop reads the input HttpRequest fine.
while((inputLine = in.readLine()) != null){
if(inputLine.equals(""))
break;
rm.send(inputLine + "\r\n");
//System.out.println(rm.receive());
}
System.out.println("Test"); //This is successfully printing.
String outputLine;
//This output loop is never entered... why?
while((outputLine = rm.receive()) != null){
System.out.println("In output loop");
if(outputLine.equals(""))
break;
out.print(outputLine + "\r\n");
out.flush();
System.out.println(outputLine);
}
rm.disconnect();
tries = maxTries;
}
} catch(IOException e) {
System.out.println("Bad");
}
}
Class #2: RequestMaker
public class RequestMaker {
private Socket socket;
PrintWriter out;
BufferedReader in;
public void connect() throws IOException {
String[] proxy = ProxyGenerator.generate().split(":");
socket = new Socket(proxy[0], Integer.parseInt(proxy[1]));
System.out.println("Connected to proxy - " + proxy[0] + ":" + proxy[1]);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void send(String s) {
out.write(s);
out.flush();
}
public String receive() throws IOException {
return in.readLine();
}
public void disconnect() {
try{
out.flush();
out.close();
in.close();
socket.close();
} catch(IOException e) {}
}
}
I tried testing this with fiddler too. I set the proxy to connect to 127.0.0.1:8888 which is Fiddler's proxy server. Once again, the request was received from the client, but the proxy on Fiddler never received it.
My question is: Why is the while loop that reads from the proxy not entering in the first place? I checked if the rm.receive() was returning "" or null using an if, and it wasn't.
Turns out I was not following the HTTP protocol properly. Had to send an empty line after writing the input request to the proxy server.
I'm new with Java and I'm trying to learn threads and socket. So decide to make simple client-server application following official java tutorial. My idea is simple - server wait for connection, if appears, it makes new thread with new socket, input and output. Client side -> make connection; new thread with socket, input, output and stdIn (to read line and after that send it to the server). But something is wrong (don't have any idea why) with my code. The connection is established, there's no exceptions. Could someone explain why doesn't work and how to fix it? Also could you have any suggestions about the code (probably it's not with best practices and things like that):
Client side:
public class Client {
private BufferedReader reader;
private Socket sock;
private PrintWriter writer;
public static void main(String[] args) {
Client client = new Client();
client.go();
}
public void go() {
setUpNetworking();
}
private void setUpNetworking() {
try{
sock = new Socket("127.0.0.1", 5000);
System.out.println("Network established");
ServerThread serverThread= new ServerThread(sock);
serverThread.start();
System.out.println("Type your message: ");
} catch (IOException e) {
System.out.println("Problem with establishing the network: " + e);
}
}
class ServerThread extends Thread {
Socket socket;
PrintWriter out;
BufferedReader in;
BufferedReader stdIn;
ServerThread(Socket socket) {
this.socket = socket;
try{
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
}catch (IOException e) {
System.out.println("Problem with trying to read/write to server: " + e);
}
}
#Override
public void run() {
String fromServer;
String fromClient;
while(true){
try{
if((fromServer = in.readLine()) != null) System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null) out.println(fromClient);
}catch(Exception e) {
System.out.println("msg exception: " + e);
}
}
}
}
}
Server side:
public class Server {
//Run server until keepGoing = false
private boolean keepGoing = true;
public static void main(String[] args) {
Server server = new Server();
server.go();
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while(keepGoing) {
Socket clientSocket = serverSocket.accept();
ClientThread t = new ClientThread(clientSocket);
t.start();
}
} catch (IOException e) {
System.out.println("Problem with socket/network: " + e);
}
}
class ClientThread extends Thread {
Socket clientSocket;
PrintWriter out;
BufferedReader in;
ClientThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try{
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
System.out.println("Problem with creating in/out: " + e);
}
}
#Override
public void run() {
String message;
while(keepGoing) {
try{
message = in.readLine();
out.println(message);
System.out.println(message);
} catch (IOException e){
System.out.println("Exception while try to read line: " + e);
}
}
}
}
}
PS I've changed a bit the code - instead of made ClientThread Class, I made new runnable class and pass that variable to thread class. Inspired by this question: "implements Runnable" vs. "extends Thread".
I think the problem is that both server and client are waiting for any input. Server:
message = in.readLine();
Client:
if((fromServer = in.readLine()) != null)
System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null)
out.println(fromClient);
But the client code already blocks on the fromServer = in.readLine() part, so it never gets to read from standard in, and thus nothing will be sent out to the server.
You could move your attempt to read from standard in to the setUpNetworking method, right after the System.out.println("Type your message: ");. Build a loop there which you exit if the user types "exit" or "quit" or something like that:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String read = "";
do {
read = stdIn.readLine();
System.out.println("Read from stdin: " + read);
serverThread.send(read);
}
while (!read.equals("exit"));
The ServerThread.send() method is simple:
void send(String string) {
System.out.println("Sending to server: " + string);
out.println(string);
}
However, to make it work, you either have to flush the stream manually after writing to out, or use the following constructor:
out = new PrintWriter(socket.getOutputStream(), true);
See the PrintWriter's JavaDoc: True means auto-flush on newline.
I tested this setup and it worked for me. I was able to send something from the client to the server.
However, this is only the first step. I would implement both reading and writing as separate threads, for both client and server. And there is no graceful shutdown of sockets implemenented yet. A more complete yet simple example can be found on Oracle.
Client side code is
try {
URL url=new URL("http://127.0.0.1:7655");
HttpURLConnection connection=(HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.connect();
PrintWriter writer = new PrintWriter(connection.getOutputStream());
writer.println("Hello");
writer.flush();
writer.close();
connection.getResponseCode();
connection.disconnect();
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: hostname");
}
Server Side code is
public static void main(String args[]) throws IOException {
ServerSocket echoServer = null;
String line;
DataInputStream is = null;
Socket clientSocket = null;
try {
echoServer = new ServerSocket(7655);
clientSocket = echoServer.accept();
while (true) {
is = new DataInputStream(clientSocket.getInputStream());
System.out.println("inside");
line = is.readLine();
System.out.println(line);
}
}catch (IOException e) {
System.out.println(e);
}finally{
is.close();
clientSocket.close();
}
}
When I run the client first time it server shows the output... second time when I run client, server doesn't show output. Is there some mistake in the code?
If I am not givng "Connection.getResponseCode" in the end server side receives null and shows null on console. Why is this necessary?
Your code is exactly designed that way.
You need to make use of multithreading in the server side on thread accepts all connection the other is your DataInputStream thread.
How i did this... i have a class all by it's self with getters and setters, and is only used for information or arrays that needed between threads. And in your main run the 2 threads that will always accept connections and read every connections.
i am creating a simple client/server app
and was able to connect multiple clients to single server.
i referred to this link client/server simple app demo
my problem is that now,i want to return some response from server to client
based on its client/ip address.
eg. if 192.123.1.1 connects the response should be xml
if 192.123.1.2 connects the response should be json.
is it possible to do?? any help will be appreciated
here is my simple server code:
public class ChatServer implements Runnable
{
private ServerSocket server = null;
private Thread thread = null;
private ChatServerThread client = null;
public ChatServer(int port)
{ try
{ System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
start();
}
catch(IOException ioe)
{ System.out.println(ioe); }
}
public void run()
{ while (thread != null)
{ try
{ System.out.println("Waiting for a client ...");
addThread(server.accept());
}
catch(IOException ie)
{ System.out.println("Acceptance Error: " + ie); }
}
}
public void addThread(Socket socket)
{ System.out.println("Client accepted: " + socket);
client = new ChatServerThread(this, socket);
try
{ client.open();
client.start();
}
catch(IOException ioe)
{ System.out.println("Error opening thread: " + ioe); }
}
public void start()
public void stop()
public static void main(String args[])
I think instead of ip check the client should ask for the type of data they want. I am not sure why you require a check on ip. But in future if you all more clients then you have to change the server code every time. Better to define the format in the client so that client can ask for data of specific type.
Not very sure about your requirement.
There is an API call Socket.getRemoteSocketAddress().toString() to get the caller IP
Socket clientSocket =server.accept();
System.out.println(" client ip address =" +clientSocket.getRemoteSocketAddress().toString());
-- once you obtained clientSocket, use below sample to write back
Socket clientSocket =server.accept();
String returMessage ="Hello from Server ";
if (clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.3")){
returMessage=returMessage +" welcome browser";
}
else if(clientSocket.getRemoteSocketAddress().toString().equals("192.168.1.4")){
returMessage=returMessage +" welcome tablet";
}
OutputStream os = clientSocket .getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returMessage);
System.out.println("Message sent to the client is "+returMessage);
bw.flush();
-- To read from client
InputStream is = clientSocket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();
System.out.println("Message received from client is "+data);
if("send_players".equals(data)){ // reading data you would need to finetune
//write playerlist
}
I have a relatively simple program where I try establish Client Server connection and at the same time I use threads in the client side to allow for multiple connections.
I run the server and then the server invokes the client constructor and passes the port connection to the client and the thread is started on the client side.
The problem I have is that when I run the server side it doesn't want to go beyond the constructor call. It seems to get stuck at the constructor.
Sorry all this sounds a bit confusing
Any thoughts perhaps
this is the server side
ServerMultipleThreads()
{
System.out.println("Starting the server first...");
try
{
ServerSoc = new ServerSocket(7777);
listening = true;
}
catch(Exception e)
{
System.out.println(e.toString());
System.exit(1);
}
System.out.println("The server has started running");
while(listening)
{
try
{
//creating the client socket and starting the new client session
new ClientSession(ServerSoc.accept());
System.out.println("The clientSession was called");
in = new DataInputStream(clientSocket.getInputStream());
BufferedReader is = new BufferedReader(new InputStreamReader(in));
os = new PrintStream(clientSocket.getOutputStream());
while(true)
{
line = is.readLine();
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("myFile,txt")), true);
out.println(line);
}
}
catch(IOException ioe)
{
System.out.println(ioe.toString());
}
}
}
and this is on client side
ClientSession(Socket s)
{
clientSocket = s;
try
{
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Welcome");
}
catch(IOException exe)
{
System.out.println(exe.toString());
}
//starting the thread
while(runner == null)
{
runner = new Thread(this);
runner.start();
}
}
public void run()
{
while(runner == Thread.currentThread())
{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String stdIn;
try
{
while((stdIn = buf.readLine()) != null)
{
out.println(stdIn);
}
}
catch(IOException exe)
{
exe.toString();
}
try
{
Thread.sleep(10);
}
catch(InterruptedException e){}
}
Kind regards
Arian
That is because ServerSocket.accept() blocks until it receives a client request.
You need to have a client calling the server, something like this:
Socket socket = new Socket(host, port);
InputStream in = socket.getInputStream();
// write some data...