import java.io.DataInputStream; import java.io.OutputStream; import java.net.Socket; /** * This class contains some starter code for communicating with an HTTP server. Note * that it's currently broken -- the GET request that it builds and sends is not valid, * but it will still get a response from the server. (A "400 Bad Request" response.) * * The main difference between this code and the sample URLReader program is that we're * implementing some of the functionality of the HttpURLConnection ourselves: We'll * open a "bare" connection with the appropriate server, build a GET request packet * ourselves and explicitly send it, then wait for the HTTP response packet to come back * from the server. That response is a complete HTTP packet, complete with header, as * you'll see when you run this program. The header isn't removed automatically as it * is with the HttpURLConnection. * * @author brichards */ public class SocketCode { // The size of the buffer (array) we use to hold incoming data. It's // sized at the moment to be large enough to contain the entire response. private static final int BUFFER_SIZE = 600; /** * All of our communication code is currently in main. By default it tries * to contact the web server at cs.pugetsound.edu, but you can pass in a * different host as a command-line argument if you wish. The basic steps * in the process are: * 1) Create a socket so that we can "connect" to the network * 2) Associate input and output streams with the socket * 3) Build the outgoing packet as a String and send it * 4) Read the resulting response as bytes (convert to chars for printing) * * The code catches some but not all exceptions that might arise. In your * final version of the code, ALL exceptions must be caught and reported * appropriately. * * @param args An array of command-line arguments * @throws Exception */ public static void main(String[] args) throws Exception { String host = "cs.pugetsound.edu"; if (args.length > 0) { host = args[0]; } // Now we can create a socket, and associate some input and // output data streams with it. Socket theSocket = null; OutputStream outgoing = null; DataInputStream incoming = null; theSocket = new Socket(host, 80); // Port 80 is HTTP outgoing = theSocket.getOutputStream(); incoming = new DataInputStream(theSocket.getInputStream()); // Build and send a (broken) GET request packet. The packet is a String, // and therefore needs to be converted to a sequence of bytes before it // can be sent. There's a getBytes() method in the String class to do that. // The \r and \n characters are CR and LF. The first pair ends the GET line, // the second pair ends the "blank line" marking the end of the packet. // Any header info could have to be included before that blank line. String packet = "GET HTTP/1.1\r\n\r\n"; System.out.println("Sending packet to "+host); outgoing.write(packet.getBytes()); // Read the resulting data and write it to our output file. We intentionally // use a DataInputStream rather than an InputStreamReader to get the data from // the socket, since we want to allow for reading binary data files like .jpgs, // but that means we need to convert it to a character string if we ever want // to print it out. This code uses a special constructor in the String class // to do that. Note that this code assumes the entire response can be retrieved // in one call to read(). You may NOT make that assumption in your finished // program. byte[] buf = new byte[BUFFER_SIZE]; int numBytes = incoming.read(buf); if (numBytes > 0) { System.out.println("Got: "+(new String(buf, 0, numBytes, "UTF-8"))); } theSocket.close(); } }