Xu Changyou
WWW is based on the client/server computing model. It consists of a Web browser (client) and a Web server (server). The two use Hypertext Transfer Protocol (HTTP) for communication, the principles of HTTP include connection, request, and response. Based on the principle of the above HTTP protocol, this article implements the GET request Web server program method, by creating a TcpListener Class Object, listening port 808; waiting, accepting the client to connect to port 808; create the input stream and output stream associated with the socket word. Then, read the client's request information. If the request type is GET, obtain the accessed HTML file name from the request information, if an HTML file exists, open the HTML file, return the HTTP header information and HTML file content to the Web browser through socket, and then close the file. Otherwise, an error message is sent to the Web browser. Finally, close the socket word connected to the corresponding Web browser.
I. Principle of the HTTP protocol
WWW is an application system that uses the Internet as the transmission media. The most basic transmission unit on WWW is Web pages. WWW is based on the client/server computing model. It consists of a Web browser (client) and a Web server (server). The two use Hypertext Transfer Protocol (HTTP) for communication. HTTP is a protocol based on TCP/IP. It is an application layer protocol between a Web browser and a Web server. It is a common, stateless, and object-oriented protocol. The principle of HTTP protocol includes four steps:
Connection: the Web browser establishes a connection with the Web server and opens a virtual file called socket. The establishment of this file indicates that the connection is established successfully.
Request: the Web browser submits a request to the Web server through socket. HTTP requests are generally GET or POST commands (POST is used for passing FORM parameters ). The format of the GET command is:
GET path/File Name HTTP/1.0
The file name indicates the accessed file, and HTTP/1.0 indicates the HTTP Version Used by the Web browser.
Response: After a Web browser submits a request, the request is sent to the Web server over HTTP. After the Web server receives the request, it processes the transaction and returns the result to the Web browser over HTTP, so that the requested page is displayed on the Web browser.
For example, if the client establishes a connection with www.mycomputer.com: 808/mydir/index.html, the GET command: GET/mydir/index.html HTTP/1.0 is sent. The Web server named www.mycomputer.comsearches for the mydirfile index.html in the file space of the website. If the file is found, the Web server sends the file content to the corresponding Web browser.
To inform the Web browser of the type of content transmitted, the Web server first Transmits some HTTP header information and then transmits the specific content (that is, the HTTP body information ), the HTTP header and HTTP body are separated by a blank line.
Common HTTP header information:
① HTTP 1.0 200 OK
This is the first line of Web server response. It lists the HTTP version numbers and response code that the server is running. The Code "200 OK" indicates that the request is complete.
(2) MIME_Version: 1.0
It indicates the MIME Version.
③ Content_type: Type
This header indicates the MIME type of the HTTP body information. For example, content_type: text/html indicates that the transmitted data is an HTML document.
④ Content_length: Length Value
It indicates the length (in bytes) of the HTTP body information ).
Close connection: After the response is over, the Web browser and the Web server must be disconnected to ensure that other Web browsers can establish a connection with the Web server.
Ii. Program Design for implementing Web server functions using C # Builder
Based on the principle of the above HTTP protocol, the method for implementing the GET request Web server program is as follows:
Create a TcpListener Class Object and listen to a port (enter any idle port such as 808, default port 80 ).
Wait and accept the client to connect to the port to obtain the socket connected to the client;
Read the request information submitted by a client from the input stream associated with the socket. The request information format is: GET path/File Name HTTP/1.0
Obtain the request type from the request information. If the request type is GET, the accessed HTML file name is obtained from the request information. When there is no HTML file name, index.html is used as the file name;
If an HTML file exists, open the HTML file, return the HTTP header information and HTML file content to the Web browser through socket, and then close the file. Otherwise, an error message is sent to the Web browser;
Close the socket word connected to the corresponding Web browser.
Iii. Complete Encoding
Start C # Builder, select File> New> Other, select Console Application in C # projects in the New item window, and click OK. Enter WebServer Name in the New Application window
The complete code of the program is as follows:
Namespace Webserver
{
Using system;
Using system. IO;
Using system. net;
Using system. net. Sockets;
Using system. text;
Using system. threading
Class MyWebServer
{
Private TcpListener myListener
Private int port = 808 // Web server port, usually 80
Public MyWebServer ()
{
Try
{
// Start listening on the port
MyListener = new TcpListener (port)
MyListener. Start ();
Console. WriteLine ("My Web Server (V1.0) Running ......");
// Start a listening process at the same time
Thread th = new Thread (new ThreadStart (StartListen ));
Th. Start ()
}
Catch (Exception e)
{
Console. WriteLine ("listener error:" + e. ToString ());
}
}
Public void SendHeader (string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
{
String sBuffer = "";
If (sMIMEHeader. Length = 0)
{
SMIMEHeader = "text/html"; // default text/html
}
SBuffer = sBuffer + sHttpVersion + sStatusCode + "/r/n ";
SBuffer = sBuffer + "Server: MyWebServer/r/n ";
SBuffer = sBuffer + "Content-Type:" + sMIMEHeader + "/r/n ";
SBuffer = sBuffer + "Accept-Ranges: bytes/r/n ";
SBuffer = sBuffer + "Content-Length:" + iTotBytes + "/r/n ";
Byte [] bSendData = Encoding. ASCII. GetBytes (sBuffer );
SendToBrowser (bSendData, ref mySocket );
Console. WriteLine ("Total Bytes:" + iTotBytes. ToString ());
}
Public void SendToBrowser (String sData, ref Socket mySocket)
{
SendToBrowser (Encoding. ASCII. GetBytes (sData), ref mySocket );
}
Public void SendToBrowser (Byte [] bSendData, ref Socket mySocket)
{
Int numBytes = 0;
Try
{
If (mySocket. Connected)
{
If (numbytes = mysocket. Send (bsenddata, bsenddata. length, 0) =-1)
Console. writeline ("socket error cannot send packet ");
Else
{
Console. writeline ("No. of bytes send {0}", numbytes );
}
}
Else
Console. writeline ("connection failed ....");
}
Catch (exception E)
{
Console. writeline ("error: {0}", e );
}
}
Public static void main ()
{
MyWebServer MWs = new MyWebServer ();
}
Public void startlisten ()
{
Int istartpos = 0;
String sRequest;
String sDirName;
String sRequestedFile;
String sErrorMessage;
String sLocalDir;
String sPhysicalFilePath;
// Virtual directory
String sMyWebServerRoot = "C: // Inetpub // wwwroot //";
String sFormattedMessage = "";
String sResponse = "";
While (true)
{
// Accept new connections
Socket mySocket = myListener. AcceptSocket ()
Console. WriteLine ("Socket Type" + mySocket. SocketType );
If (mySocket. Connected)
{
Console. WriteLine ("/n client connection !! /N ===========================/ nCLient IP {0}/n ", mySocket. RemoteEndPoint)
Byte [] bReceive = new Byte [1, 1024]
Int I = mySocket. Receive (bReceive, bReceive. Length, 0)
// Convert to string type
String sBuffer = Encoding. ASCII. GetString (bReceive );
// Process the "get" request type
If (sBuffer. Substring (0, 3 )! = "GET ")
{
Console. WriteLine ("processing get request type ..");
MySocket. Close ();
Return;
}
// Find the location of "HTTP"
IStartPos = sBuffer. IndexOf ("HTTP", 1 );
String sHttpVersion = sBuffer. Substring (iStartPos, 8 );
// Obtain the request type and file directory file name
SRequest = sBuffer. Substring (0, iStartPos-1 );
SRequest. Replace ("//","/");
// Add "/" if the end is not the file name or the end is not "/"
If (sRequest. IndexOf (".") <1 )&&(! SRequest. EndsWith ("/")))
{
SRequest = sRequest + "/";
}
// Get the request file name
IStartPos = sRequest. LastIndexOf ("/") + 1;
SRequestedFile = sRequest. Substring (iStartPos );
// Obtain the request file directory
SDirName = sRequest. Substring (sRequest. IndexOf ("/"), sRequest. LastIndexOf ("/")-3 );
// Obtain the physical path of the virtual directory
SLocalDir = sMyWebServerRoot;
Console. WriteLine ("request file directory:" + sLocalDir );
If (sLocalDir. Length = 0)
{
SErrorMessage = "<H2> Error !! Requested Directory does not exists </H2> <Br> ";
SendHeader (sHttpVersion, "", sErrorMessage. Length, "404 Not Found", ref mySocket );
SendToBrowser (sErrorMessage, ref mySocket );
MySocket. Close ();
Continue;
}
If (sRequestedFile. Length = 0)
{
// Get the request file name
SRequestedFile = "index.html ";
}
// Obtain the request file type (set to text/html)
String sMimeType = "text/html ";
SPhysicalFilePath = sLocalDir + sRequestedFile;
Console. WriteLine ("request file:" + sPhysicalFilePath );
If (File. Exists (sPhysicalFilePath) = false)
{
SErrorMessage = "<H2> 404 Error! File Does Not Exists... </H2> ";
Sendheader (shttpversion, "", serrormessage. length, "404 Not Found", ref mysocket );
Sendtobrowser (serrormessage, ref mysocket );
Console. writeline (sformattedmessage );
}
Else
{
Int itotbytes = 0;
Sresponse = "";
Filestream FS = new filestream (sphysicalfilepath, filemode. Open, fileaccess. Read, fileshare. Read );
Binaryreader reader = new binaryreader (FS );
Byte [] bytes = new byte [fs. Length];
Int read;
While (read = reader. Read (bytes, 0, bytes. Length ))! = 0)
{
SResponse = sResponse + Encoding. ASCII. GetString (bytes, 0, read );
ITotBytes = iTotBytes + read;
}
Reader. Close ();
Fs. Close ();
SendHeader (sHttpVersion, sMimeType, iTotBytes, "200 OK", ref mySocket );
SendToBrowser (bytes, ref mySocket );
}
MySocket. Close ();
}
}
}
}
}
Compile the file into an EXE file to implement a simple WEB server function! Set a virtual directory for testing!
In the C:/Inetpub/wwwrootdirectory, the new HTML file index.html is as follows:
<Html>
<Head>
<Meta http-equiv = "Content-Type"
Content = "text/html; charset = gb2312">
<Title> test </title>
</Head>
<Body>
<H1> Web server developed by C # builder
<P> test !!!!! </P>
</Body>
</Html>
Press F9 to run the program. If Port 808 is not occupied, the following window is displayed.
(Figure 1)
Open your browser and enter http: // localhost: 808
(Figure 2)
Iv. Conclusion
Here, a simple web server is ready. If you are interested, change and enhance its functions. In the C # builder 1.0 personal test + Win2000 environment, the debugging is successful. Source code can go to my website to download http://yousoft.hi.com.cn