Avatar of ocean O
ocean O
 asked on

TCP socket

Hi, I am new to TCP socket. I have a question about socket. I need modify the TCP Client program below, to fetch the webpage at: www.cs.montclair.edu/~wangd/pubs.html. I run the code below, but got an 404 error.

Any inputs are appreciated.

Below is the code.


import java.io.*;
import java.net.*;

class TCPClient {  
   public static void main(String argv[]) throws Exception
   {    
         String sentence;  
       String modifiedSentence;
     
      BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));  
       
        Socket clientSocket = new Socket("cs.montclair.edu", 80);

      DataOutputStream outToServer = new
DataOutputStream(clientSocket.getOutputStream());  
      BufferedReader inFromServer = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));    

     System.out.println("Type in any sentence: ");    
     sentence = inFromUser.readLine();    
    System.out.println(" in sentence: "+sentence);
     outToServer.writeBytes("GET/~wangd/pubs.html" + '\n');  
    outToServer.flush();
    modifiedSentence = inFromServer.readLine();  
    System.out.println("FROM SERVER: " + modifiedSentence);    
    clientSocket.close();    
    }
}

* WebSocketsTCP/IPJava

Avatar of undefined
Last Comment
CEHJ

8/22/2022 - Mon
Gerwin Jansen

I'm not that familiar with Java but your URL would need a space after the GET:

outToServer.writeBytes("GET /~wangd/pubs.html" + '\n');  
ocean O

ASKER
Hi Gerwin:
Thanks for the comments, I tried with the space after the GET, but I still get an error:
Exception in thread "main" java.net.SocketTimeoutException: Read timed out
dpearson

A socket is a very low level way to communicate.  You are looking to send an "HTTP Request".  Currently you are sending the actual text string "GET /~wangd/pubs.html".  But that's not an HTTP Request (which has a whole complex format for how the data is prepared and sent).

You almost certainly don't want to do this using a raw TCP Socket.

Instead you should use a library - which will itself using a TCP socket to do the work.
Have a look at the HTTPClient library, with an example shown here:
https://openjdk.java.net/groups/net/httpclient/recipes.html

The "URI" passed in would be a normal url, like you'd see in the top of a browser, like
"http://cs.montclair.edu/~wangd/pubs.html"
and the first example on that page shows how to execute a "GET" request.

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
David Favor

As @dperason mentioned.

TCP != HTTP

If you're trying to access HTTP/HTTPS you'll likely use wget, curl, httrack or maybe a libcurl binding for Java.

Or you'll have to rewrite one of these tools from scratch... which is not recommended, as this would take a significant amount of time.

Another options is to use a very lightweight program like netcat, if curl or wget are to heavy.
CEHJ

You almost certainly don't want to do this using a raw TCP Socket.
Quite right. Unless of course  this is a HTTP learning exercise. If that's the case, you're doing things back to front. First you need to know the protocol before coding. As someone pointed out, it's clear that you don't yet know it, so you need to learn it first.
SOLUTION
krakatoa

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ocean O

ASKER
Hi Krakatoa:
Thank you for the code, but I got an error when I try to compile the code:
TCPClients.java:3: error: package java.net.http does not exist
import java.net.http.*;
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
CEHJ

Have you got an old version of the JDK? That need at least Java 11
dpearson

Also it's important to recognize that Krakatoa's implementation still includes the original code opening a TCP socket to the server.

This however is not doing anything and should be removed.

The HttpClient library is opening another socket internally and doing the work...as I suggested at the top of the question here :)

Doug
krakatoa

Well the server will give a response over that socket, which is the written to the stdout. But it stayed in just pro forma.
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
dpearson

The server will respond - but there's basically two completely unrelated communications happening here, that are both occurring in the same function.

It's like as if I called up one friend on my home phone and another friend on my cell phone and then wrote down what I was hearing from my two friends.  It's two unrelated conversations.  And to further complete the analogy I would put one of the phones on "mute" - so my friend couldn't hear me :)  The TCP socket here will not get a valid response since we're not sending a valid request.

It might be simpler to just focus on one of these conversations (the HTTPClient one) which is actually going to work.  The other one (the TCP socket) will not produce a successful response (since it's not sending a valid HTTP request).  That code can be deleted from this example and what remains is all that is needed.
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
dpearson

Exactly CEHJ :)

And we end up with something very akin to the first sample here:
https://openjdk.java.net/groups/net/httpclient/recipes.html

Doug

krakatoa

Doug, as I said, I left that connection in just to show a return from the server, as the other channel was explicitly for the request. Also, it should be evident to the OP from the fact that there was no counterpart in the other direction, that it had been left in to highlight the point. ;)
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
CEHJ

:) But don't forget that was krakatoa's code