Java implements HTTP Server

Source: Internet
Author: User
Tags ranges

Java Socket is used to implement a simple HTTP server that can process get, post, and multipart POST with an attachment. Although I encountered many problems in the middle, I had a discussion with several experts on the Forum and solved the problem. If you think the program does not understand some places, you can refer to this post: http://topic.csdn.net/u/20090625/22/59a5bfc8-a6b6-445d-9829-ea6d462a4fe6.html.

Although the parsing of the HTTP header is not very standard, the original byte stream should have been used. I adopted a compromise solution using datainputstream.

This code is practical = 0, but it can help you understand the HTTP protocol well, and most other application-layer protocols are like this.

If you have never understood the HTTP protocol before, you are advised to search and read it first, or you can use the following code to simply check what data is sent between the browser and the server.

Myhttpclient. Java: simulates browser behavior, sends a GET/POST request to the server, and then prints the message returned by the server. In this way, you can check which messages the server sends to the browser when a request arrives.

Package socket; </P> <p> Import Java. io. *; <br/> Import java.net. *; </P> <p> public class myhttpclient {<br/> Public static void main (string [] ARGs) throws exception {<br/> inetaddress Inet = inetaddress. getbyname ("www.baidu.com"); <br/> system. out. println (inet. gethostaddress (); <br/> Socket socket = new socket (inet. gethostaddress (), 80); <br/> inputstream in = socket. getinputstream (); <br/> outputstream out = Socket. getoutputstream (); <br/> bufferedreader reader = new bufferedreader (New inputstreamreader (in); <br/> printwriter writer = new printwriter (out); <br/> writer. println ("Get/home.html HTTP/1.1"); // home.html Is About Baidu's page <br/> writer. println ("accept: image/GIF, image/X-xbitmap, image/JPEG, image/pjpeg, application/X-Shockwave-flash, application/XAML + XML, application/vnd. MS-xpsdocument, application/X-m S-xbap, application/X-MS-application, application/MSWord, application/vnd. MS-Excel, application/vnd. MS-PowerPoint, */* "); <br/> writer. println ("Accept-language: En-US, ZH-CN; q = 0.5"); <br/> writer. println ("Accept-encoding: gzip, deflate"); <br/> writer. println ("Host: www.baidu.com"); <br/> writer. println ("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; sv1 ;. net CLR 1.1.4322 ;. net CLR 2.0. 50727 ;. net CLR 3.0.04506.30 ;. net CLR 3.0.20.6.2152 ;. net CLR 3.5.30729) "); <br/> writer. println ("connection: keep-alive"); <br/> writer. println (); <br/> writer. flush (); <br/> string line = reader. readline (); <br/> while (line! = NULL) {<br/> system. out. println (line); <br/> line = reader. readline (); <br/>}< br/> reader. close (); <br/> writer. close (); <br/>}< br/>}

Myserver. Java: Simulate the server to receive browser requests and print the entire request message. Run the program and test it in a browser.

Package socket; </P> <p> Import Java. io. *; <br/> Import java.net. *; </P> <p> public class myserver {<br/> Public static void main (string [] ARGs) throws ioexception {<br/> serversocket svrsocket = new serversocket (8080); <br/> while (true) {<br/> Socket socket = svrsocket. accept (); <br/> // a buffer that is large enough <br/> byte [] Buf = new byte [1024*1024]; <br/> inputstream in = socket. getinputstream (); <br/> int byteread = in. read (BUF, 0, 1024*1024); <br/> string datastring = new string (BUF, 0, byteread); <br/> system. out. println (datastring); <br/> in. close (); <br/> socket. close (); <br/>}< br/>

Main Program myhttpserver.

Package socket; </P> <p> Import Java. io. *; <br/> Import java.net. *; <br/>/** <br/> * myhttpserver implements a simple HTTP server, you can get the content submitted by the user <br/> * and give the user a response <br/> * due to the time relationship, the processing of HTTP headers is not standard <br/> * for uploading attachments, currently, only one attachment can be uploaded by parsing and the attachment is located in the first position. <br/> * reprinted please indicate from http://blog.csdn.net/sunxing007 <br/> ***/<br/> public class myhttpserver {<br/> // server root directory, post.html, put upload.html in this location <br/> Public static string web_root = "C:/root"; <Br/> // port <br/> private int port; <br/> // URL of the file requested by the user <br/> private string requestpath; <br/> // mltipart/form-data submit the post separator. <br/> private string boundary = NULL; <br/> // The length of the body of the POST request <br/> private int contentlength = 0; </P> <p> Public myhttpserver (string root, int port) {<br/> web_root = root; <br/> This. port = port; <br/> requestpath = NULL; <br/>}< br/> // process get requests <br/> private void dog Et (datainputstream reader, outputstream out) throws exception {<br/> If (new file (web_root + this. requestpath ). exists () {<br/> // find the file requested by the user under the root directory of the server and send it back to the browser <br/> inputstream filein = new fileinputstream (web_root + this. requestpath); <br/> byte [] Buf = new byte [filein. available ()]; <br/> filein. read (BUF); <br/> out. write (BUF); <br/> out. close (); <br/> filein. close (); <br/> reader. close (); <br/> SY Stem. out. println ("request complete. "); <br/>}< br/> // process post requests <br/> private void dopost (datainputstream reader, outputstream out) throws exception {<br/> string line = reader. readline (); <br/> while (line! = NULL) {<br/> system. out. println (line); <br/> line = reader. readline (); <br/> If ("". equals (line) {<br/> break; <br/>} else if (line. indexof ("Content-Length ")! =-1) {<br/> This. contentlength = integer. parseint (line. substring (line. indexof ("Content-Length") + 16); <br/>}< br/> // indicates that you want to upload an attachment and jump to the domultipart method. <Br/> else if (line. indexof ("multipart/form-Data ")! =-1) {<br/> // obtain the delimiter of multiltipart <br/> This. boundary = line. substring (line. indexof ("boundary") + 9); <br/> This. domultipart (reader, out); <br/> return; <br/>}< br/> // continue reading normal post (no attachment) submitted data <br/> system. out. println ("begin reading posted data ...... "); <br/> string dataline = NULL; <br/> // The Post Data body sent by the user <br/> byte [] Buf = {}; <br/> int size = 0; <br/> If (this. contentlength! = 0) {<br/> Buf = new byte [this. contentlength]; <br/> while (size <this. contentlength) {<br/> int c = reader. read (); <br/> Buf [size ++] = (byte) C; </P> <p >}< br/> system. out. println ("the data user posted:" + new string (BUF, 0, size )); <br/>}< br/> // content sent back to the browser <br/> string response = ""; <br/> response + = "HTTP/1.1 200 OK/N"; <br/> response + = "server: sunpache 1.0/N "; <br/> response + = "Content-Type: Text/html/N "; <br/> response + =" last-modified: Mon, 11 Jan 1998 13:23:42 GMT/N "; <br/> response + = "Accept-ranges: bytes"; <br/> response + = "/N "; <br/> string body = "<HTML> <pead> <title> test server </title> </pead> <body> <p> post OK: </P> "+ new string (BUF, 0, size) +" </body> </ptml> "; <br/> system. out. println (body); <br/> out. write (response. getbytes (); <br/> out. write (body. getbytes (); <br/> out. Flush (); <br/> reader. close (); <br/> out. close (); <br/> system. out. println ("request complete. "); <br/>}< br/> // process attachments <br/> private void domultipart (datainputstream reader, outputstream out) throws exception {<br/> system. out. println ("domultipart ...... "); <br/> string line = reader. readline (); <br/> while (line! = NULL) {<br/> system. out. println (line); <br/> line = reader. readline (); <br/> If ("". equals (line) {<br/> break; <br/>} else if (line. indexof ("Content-Length ")! =-1) {<br/> This. contentlength = integer. parseint (line. substring (line. indexof ("Content-Length") + 16); <br/> system. out. println ("contentlength:" + this. contentlength); <br/>} else if (line. indexof ("boundary ")! =-1) {<br/> // obtain the multipart separator <br/> This. boundary = line. substring (line. indexof ("boundary") + 9); <br/>}< br/> system. out. println ("begin get data ...... "); <br/>/* The comment below is the full text of a request with an attachment sent by a browser, all Chinese characters are descriptive texts ***** <br/> <pttp header content omitted> <br/> ............ <br/> cache-control: No-Cache <br/> <there is a blank line, indicates that the following content is the body to be submitted> <br/> ----------------------------- 7d925132131f6 <This is a multipart separator> <br/> content-disposit Ion: Form-data; name = "myfile"; filename = "mywork.doc" <br/> Content-Type: text/plain </P> <p> <attachment body> .......................... .............. <br/> .................................... ............. </P> <p> --------------------------- 7d925133691f6 <This is a multipart separator> <br/> content-Disposition: Form-data; name = "myname" <other fields or attachments> <br/> <there is a blank line here> <br/> <content of other fields or attachments> <br/> ------------------------- 7d9251345 01f6 -- <this is the multipart separator, the last delimiter has two more separators-> <br/> ***************************** *********************************/<br/> /** <br/> * the above comment is a full-text post model of the multipart type with attachments, <br/> * If (this. contentlength! = 0) {<br/> // read all submitted bodies, including attachments and other fields, to Buf. <br/> byte [] Buf = new byte [this. contentlength]; <br/> int totalread = 0; <br/> int size = 0; <br/> while (totalread <this. contentlength) {<br/> size = reader. read (BUF, totalread, this. contentlength-totalread); <br/> totalread + = size; <br/>}< br/> // you can use Buf to construct a string, you can use strings to conveniently calculate the attachment location <br/> string datastring = new string (BUF, 0, totalread); <br/> system. Out. println ("the data user posted:/N" + datastring); <br/> int Pos = datastring. indexof (Boundary); <br/> // The Position of the first attachment is skipped after four rows <br/> Pos = datastring. indexof ("/N", POS) + 1; <br/> Pos = datastring. indexof ("/N", POS) + 1; <br/> Pos = datastring. indexof ("/N", POS) + 1; <br/> Pos = datastring. indexof ("/N", POS) + 1; <br/> // start position of the attachment <br/> int start = datastring. substring (0, POS ). getbytes (). length; <br/> P OS = datastring. indexof (boundary, POS)-4; <br/> // end position of the attachment <br/> int end = datastring. substring (0, POS ). getbytes (). length; <br/> // locate filename <br/> int filenamebegin = datastring. indexof ("FILENAME") + 10; <br/> int filenameend = datastring. indexof ("/N", filenamebegin); <br/> string filename = datastring. substring (filenamebegin, filenameend); <br/>/** <br/> * Sometimes the uploaded file displays the complete file name path, such as C:/my file/Some DIR/project.doc <br/> * only names of files are displayed, such as myphoto.jpg. <br/>. <Br/> */<br/> If (filename. lastindexof ("//")! =-1) {<br/> filename = filename. substring (filename. lastindexof ("//") + 1); <br/>}< br/> filename = filename. substring (0, filename. length ()-2); <br/> outputstream fileout = new fileoutputstream ("C: //" + filename); <br/> fileout. write (BUF, start, end-Start); <br/> fileout. close (); <br/> fileout. close (); <br/>}< br/> string response = ""; <br/> response + = "HTTP/1.1 200 OK/N "; <br/> response + = "server: sunpache 1.0/N"; <br/> response + = "Content-Type: text/html/N "; <br/> response + = "last-modified: Mon, 11 Jan 1998 13:23:42 GMT/N"; <br/> response + = "Accept-ranges: bytes "; <br/> response + = "/N"; <br/> out. write ("<HTML> <pead> <title> test server </title> </pead> <body> <p> post is OK </P> </body> </ptml> ". getbytes (); <br/> out. flush (); <br/> reader. close (); <br/> system. out. println ("request complete. "); <br/>}</P> <p> Public void Service () throws exception {<br/> serversocket = new serversocket (this. port); <br/> system. out. println ("server is OK. "); <br/> // enable serversocket to wait for user requests to arrive, then process the request according to the request type <br/> // here I only process get and post <br/> // post can parse a single attachment <br /> while (true) {<br/> Socket socket = serversocket. accept (); <br/> system. out. println ("new request coming. "); <br/> datainputstream reader = new datainputstream (socket. getinputstream (); <br/> string line = reader. readline (); <br/> string method = line. substring (0, 4 ). trim (); <br/> outputstream out = socket. getoutputstream (); <br/> This. requestpath = line. split ("") [1]; <br/> system. out. println (method); <br/> If ("get ". specified signorecase (method) {<br/> system. out. println ("do get ...... "); <br/> This. doget (reader, out); <br/>} else if ("Post ". specified signorecase (method) {<br/> system. out. println ("do post ...... "); <br/> This. dopost (reader, out); <br/>}< br/> socket. close (); <br/> system. out. println ("socket closed. "); <br/>}< br/> Public static void main (string ARGs []) throws exception {<br/> myhttpserver Server = new myhttpserver ("C:/root", 8080); <br/> server. service (); <br/>}< br/>}

The test files post.html and upload.html are all placed under the web_root defined by the program above.

Post.html: process common post requests

<HTML> <br/> <pead> <br/> <title> test my server </title> <br/> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8 "> <br/> </pead> <br/> <body> <br/> <p> upload </P> <br/> from http://blog.csdn.net/sunxing007 <br> <br/> <form name = "uploadform" method = "Post" Action = "http: // localhost: 8080/"> <br/> <input type =" text "name =" myname "/> <br/> <select name =" myage "> <br/> <option value = "18"> 18 </option> <br/> <option value = "20"> 20 </option> <br/> <option value =" 22 "> 22 </option> <br/> </SELECT> <br/> <input type =" Submit "value =" sumit "> <br/> </form> <br/> </body> <br/> </ptml> </P> <p>

Upload.html: Test POST requests with attachments

<Head> <br/> <title> my page </title> <br/> <style> <br/> table {<br/> border-collapse: collapse; <br/>}< br/> </style> <br/> </pead> <br/> <body> <br/> from http://blog.csdn.net/sunxing007 <br> <br/> <form action = 'HTTP: // localhost: 8080/'method = 'post' enctype = 'multipart/form-data'> <br/> file: <input type = 'file' name = 'myfile'/> <br/> <input type = 'submit '/> <br/> </form> <br /> </body> <br/> </ptml>

After myhttpserver runs, enter http: // localhost: 8080/post.html and http: // localhost: 8080/upload.html in the browser to perform the test.

Reprinted please indicate from http://blog.csdn.net/sunxing007

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.