A simple httpserver is implemented with the Java socket to handle the GET, post, and multipart type of post with an attachment. Although encountered in the middle of a lot of problems, just through the forum and a few experts to communicate, the problem has been overcome. Suppose you think that there are some places in the program that you don't see clearly and can take a look at this post: http://topic.csdn.net/u/20090625/22/59a5bfc8-a6b6-445d-9829-ea6d462a4fe6.html.
Although parsing the HTTP header is not very canonical, it should have used the original byte stream, I took a compromise scheme, with DataInputStream.
The usefulness of this code is ==0, but it can help to understand the HTTP protocol very well, and then most of the other application layer protocols.
Suppose you never know the HTTP protocol, it is recommended to search for it first, or you can use the following code to simply see what data the browser and server are sending to each other.
Myhttpclient.java: simulates the behavior of the browser, sends a GET/POST request to the server, and prints out the message returned by the server. This allows you to see exactly what messages the server sends to the browser after a request arrives.
Package Socket;import Java.io.*;import java.net.*;p ublic class Myhttpclient {public static void main (string[] args) throw s exception{inetaddress inet = Inetaddress.getbyname ("www.baidu.com"); System.out.println (Inet.gethostaddress ()); Socket socket = new Socket (inet.gethostaddress (), InputStream in = Socket.getinputstream (); OutputStream out = Socket.getoutputstream (); BufferedReader reader = new BufferedReader (new InputStreamReader (in)); PrintWriter writer = new PrintWriter (out); Writer.println ("get/home.html http/1.1");// Home.html is about Baidu page 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-MS-XBAP, application/ X-ms-application, Application/msword, Application/vnd.ms-excel, Application/vnd.ms-powerpoint, */* "); Writer.println ("accept-language:en-us,zh-cn;q=0.5"); Writer.println ("Accept-encoding:gzip, deflate"); Writer.println ("Host:www.baidu.com"); 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.4506.2152;. NET CLR 3.5.30729); writer.pr Intln ("connection:keep-alive"); Writer.println (); Writer.flush (); String line = Reader.readline (), while (Line!=null) {System.out.println (line), line = Reader.readline ();} Reader.close (); Writer.close ();}}
Myserver.java: Simulates server-side receive browser requests, then prints the entire requested message. After the program executes, it is tested directly with the browser.
Package socket;import java.io.*;import java.net.*;p ublic class MyServer {public static void main (string[] args) throw s Ioexception{serversocket svrsocket = new ServerSocket (8080), while (true) {Socket socket = svrsocket.accept ();// A buffer large enough byte[] buf = new Byte[1024*1024];inputstream in = Socket.getinputstream (); int byteread = In.read (buf, 0, 1024*102 4); String datastring = new String (buf, 0, Byteread); System.out.println (datastring); In.close (); Socket.close (); }}}
Main program Myhttpserver.
Package Socket;import Java.io.*;import java.net.*;/** * Myhttpserver implements a simple httpserver end that can get user-submitted content * and give the User a response * Due to the time of the relationship, the processing of HTTP headers is not standardized * for uploading attachments, temporary only can parse only upload an attachment and attachment location in the first case * reproduced please specify from http://blog.csdn.net/sunxing007 * **/public Class Myhttpserver {//server root folder, post.html, upload.html are placed in the location public static String Web_root = "C:/root"; Port private int port; The URL of the file requested by the user private String Requestpath; Mltipart/form-data method submits the delimiter for post, private String boundary = null; The length of the body of the post submission request is private int contentlength = 0; Public Myhttpserver (String root, int port) {web_root = root; This.port = port; Requestpath = null; }//Handle GET request private void doget (DataInputStream reader, outputstream out) throws Exception {if (New File (web_ Root + This.requestpath. Exists ()) {//from the server root folder to find the file requested by the user and sent back to the browser inputstream Filein = new FILEINP Utstream (Web_root + this.requestpath); byte[] buf = new Byte[filein. available ()]; Filein.read (BUF); Out.write (BUF); Out.close (); Filein.close (); Reader.close (); SYSTEM.OUT.PRINTLN ("request complete."); }}//processing POST request private void DoPost (DataInputStream reader, outputstream out) throws Exception {String Lin E = Reader.readline (); while (line! = null) {System.out.println (line); line = Reader.readline (); if ("". Equals (line)} {break; } else if (Line.indexof ("Content-length")! =-1) {this.contentlength = Integer.parseint (Line.substring (Lin E.indexof ("content-length") + 16); }//indicates to upload an attachment and jumps to the Domultipart method. else if (Line.indexof ("Multipart/form-data")! =-1) {//Multiltipart delimiter this.boundary = line. SUBSTRING (line.indexof ("boundary") + 9); This.domultipart (reader, out); Return } } Continue to read System.out.println ("Begin reading posted data ...") submitted by normal post (no attachments); String dataline = null; The user sends the Post data body byte[] buf = {}; int size = 0; if (this.contentlength! = 0) {buf = new byte[this.contentlength]; while (size<this.contentlength) {int c = reader.read (); buf[size++] = (byte) c; } System.out.println ("The data user posted:" + New String (buf, 0, size)); }//Send back content to the browser String response = ""; Response + = "http/1.1 ok/n"; Response + = "Server:sunpache 1.0/n"; Response + = "content-type:text/html/n"; Response + = "Last-modified:mon, 1998 13:23:42 gmt/n"; Response + = "Accept-ranges:bytes"; Response + = "/n"; String BODY = "<ptml><pead><title>test server</title></pead><body><p> Post ok:</p> "+ New String (buf, 0, siZe) + "</body></ptml>"; System.out.println (body); Out.write (Response.getbytes ()); Out.write (Body.getbytes ()); Out.flush (); Reader.close (); Out.close (); SYSTEM.OUT.PRINTLN ("request complete."); }//Processing attachment private void Domultipart (DataInputStream reader, outputstream out) throws Exception {System.out.pri Ntln ("Domultipart ..."); String line = Reader.readline (); while (line! = null) {System.out.println (line); line = Reader.readline (); if ("". Equals (line)} {break; } else if (Line.indexof ("Content-length")! =-1) {this.contentlength = Integer.parseint (Line.substring (Lin E.indexof ("content-length") + 16); System.out.println ("ContentLength:" + this.contentlength); } else if (Line.indexof ("boundary")! =-1) {//get multipart delimiter this.boundary = line.substring (Line.indexof ("bOundary ") + 9); }} System.out.println ("Begin get Data ..."); /* The following gaze is the full text of a browser sending a request with an attachment, all Chinese is descriptive text * * * * * * * <pttp head content slightly > ... Cache-control:no-cache < Here's a blank line that says the next thing is to submit the body >-----------------------------7d925134501f6< This is Mul Tipart separators > Content-disposition:form-data; Name= "MyFile"; Filename= "Mywork.doc" Content-type:text/plain < Accessories body ........ ....................... ....-----------------------------7d925134501f6<.--This is mu, and .....????????????????????????? Ltipart separators > Content-disposition:form-data; Name= "MyName" < other fields or accessories > < There is a blank line > < the contents of other fields or attachments >-----------------------------7d925134 501f6--< This is the multipart delimiter, the last delimiter more than two--****************************************************************/ /** * The gaze above is a full-text model of post with an attachment multipart type, * to get the attachment out, is to find the attachment bodyStart position and End position * **/if (this.contentlength! = 0) {//Put all the submitted body, including attachments and other fields, first read to BUF. byte[] buf = new Byte[this.contentlength]; int totalread = 0; int size = 0; while (Totalread < this.contentlength) {size = Reader.read (buf, Totalread, This.contentlength-totalre AD); Totalread + = size; }//Use BUF to construct a string that can easily be used to calculate the location of the attachment in string datastring = new String (buf, 0, Totalread); SYSTEM.OUT.PRINTLN ("The data user posted:/n" + datastring); int pos = datastring.indexof (boundary); Below 4 lines is the first attachment position pos = Datastring.indexof ("/n", POS) + 1; pos = Datastring.indexof ("/n", POS) + 1; pos = Datastring.indexof ("/n", POS) + 1; pos = Datastring.indexof ("/n", POS) + 1; Attachment start position int start = datastring.substring (0, POS). GetBytes (). length; pos = datastring.indexof (boundary, POS)-4; Attachment end Position int end = datastring.substring (0, POS). GetBytes (). length; below find the filename int filenamebegin = datastring.indexof ("filename") + 10; int filenameend = Datastring.indexof ("/n", Filenamebegin); String fileName = datastring.substring (Filenamebegin, filenameend); /** * Sometimes uploaded files show the full file name path, such as C:/My File/somedir/project.doc * But sometimes only show the name of the file, for example Myphoto.jpg. * So you need to make an inference. */if (Filename.lastindexof ("//")!=-1) {fileName = filename.substring (Filename.lastindexof ("//") + 1); } fileName = filename.substring (0, Filename.length ()-2); OutputStream fileout = new FileOutputStream ("c://" + fileName); Fileout.write (buf, start, End-start); Fileout.close (); Fileout.close (); } String response = ""; Response + = "http/1.1 ok/n"; Response + = "Server:sunPache 1.0/n "; Response + = "content-type:text/html/n"; Response + = "Last-modified:mon, 1998 13:23:42 gmt/n"; Response + = "Accept-ranges:bytes"; Response + = "/n"; Out.write ("<ptml><pead><title>test server</title></pead><body><p>post Is Ok</p></body></ptml> ". GetBytes ()); Out.flush (); Reader.close (); SYSTEM.OUT.PRINTLN ("request complete."); public void Service () throws Exception {ServerSocket serversocket = new ServerSocket (this.port); SYSTEM.OUT.PRINTLN ("Server is OK."); Turn on ServerSocket wait for the user request to arrive and then process according to the requested category//Here I am only dealing with get and post, where post has the ability to parse a single attachment while (true) { Socket socket = serversocket.accept (); SYSTEM.OUT.PRINTLN ("New request coming."); DataInputStream reader = new DataInputStream ((Socket.getinputstream ())); String line = Reader.readline (); String method = line.substring (0, 4). Trim (); OutputStream out = Socket.getoutputstream (); This.requestpath = Line.split ("") [1]; System.out.println (method); if ("Get". Equalsignorecase (method)) {System.out.println ("do GET ..."); This.doget (reader, out); } else if ("Post". Equalsignorecase (method)) {System.out.println ("do post ..."); This.dopost (reader, out); } socket.close (); SYSTEM.OUT.PRINTLN ("socket closed."); }} public static void Main (String args[]) throws Exception {myhttpserver Server = new Myhttpserver ("C:/root ", 8080); Server.service (); }}
Test file post.html, upload.html are placed in the above program defined Web_root below.
post.html: Handling a normal POST request
<ptml> <pead> <title>test my server</title> <meta http-equiv= "Content-type" content= " text/html; Charset=utf-8 "> </pead> <body> <p>upload</p> from http://blog.csdn.net/sunxing007<br ><form name= "Uploadform" method= "post" action= "http://localhost:8080/" ><input type= "text" Name= "MyName" /><br><select name= "Myage" > <option value= "All" >18</option> <option value= ">20" </option> <option value= ">22</option></select><br><input type=" Submit "value=" Sutmit "></form></body> </ptml>
upload.html: Test tape attachment for POST request
<pead><title>my page</title><style> table{border-collapse:collapse; }</style></pead><body> from http://blog.csdn.net/sunxing007<br> <form action= '/http localhost:8080/' method= ' post ' enctype= ' multipart/form-data ' > File: <input type= ' file ' name= ' myfile '/>< br> <input type= ' Submit '/> </form></body></ptml>
Everything is ready, and after the myhttpserver is executed, the browser enters http://localhost:8080/post.html and http://localhost:8080/upload.html to test.
Reprint please specify from http://blog.csdn.net/sunxing007