Web服务器的基本原理:
Web服务器运行,进入侦听状态 Web浏览器与服务器建立连接并通过HTTP协议向服务器发送请求 Web服务器作出应答,向Web浏览器发送相关数据 Web服务器断开与Web浏览器的连接
二、Web服务器的实现: 基于上面的原理,让我们用 Borland C++Builder 5 来做一个Web服务器。该Web服务器默认的Web发布路径为“C:\WEB”,请修改为相应的Web发布路径。 首先,在Form1中添加两个Label(标签)、两个Edit(编辑框)、两个Button(命令按钮)、一个Memo(备注框)以及一个ServerSocket(服务端Socket)组件。设置它们的布局、大小以达到美观。 然后,双击Form1打开Form1的OnCreate事件,出现以下代码: void __fastcall TForm1::FormCreate(TObject *Sender) { } 在{ }中间加入以下代码来响应Form1的建立事件:
Form1-$#@62;Caption="FDL Web 服务器 1.0"; Form1-$#@62;Font-$#@62;Name="宋体"; Form1-$#@62;Font-$#@62;Size=9; Label1-$#@62;Caption="服务器地址"; Label2-$#@62;Caption="发布路径"; //设置 Edit2-$#@62;Text="c:\\web\($%$43%^#ASD#2@$#f$%^); Button1-$#@62;Caption="消除消息"; Button2-$#@62;Caption="退出"; //设置端口,一般浏览器的默认端口为80 ServerSocket1-$#@62;Port = 80; Memo1-$#@62;ScrollBars=ssVertical;//出现垂直流动条 Memo1-$#@62;Lines-$#@62;Add("开始侦听"); //设置服务类型,让服务器自动应答 ServerSocket1-$#@62;ServerType=stThreadBlocking; ServerSocket1-$#@62;Active=true;//开始侦听 //得到本机地址 Edit1-$#@62;Text ="http://" + ServerSocket1-$#@62;Socket-$#@62;LocalHost+"/"; Edit1-$#@62;ReadOnly=true;//设置Edit1为只读
在Object Inspector(对象查看器)的对象名称查看栏的下拉式列表中选择Form1,选择Events(事件)选项卡,双击OnCloseQuery事件选项右边的空白处打开Form1的OnCloseQuery事件,加入这么一句:
ServerSocket1-$#@62;Close();//关闭服务 用上面的方法打开ServerSocket1的OnAccept事件,也可以直接双击ServerSocket1组件来打开该事件,加入以下的代码:
AnsiString filemessage; filemessage=Socket-$#@62;ReceiveText(); filemessage=filemessage.Trim(); try { int iFileHandle; int iFileLength; int iBytesRead; int tx=0,ty; char *pszBuffer; for(int J=0;J$#@60;filemessage.Length()-1;J++) { if(filemessage.SubString(J,1)==" ") { if(tx==0) tx=J+1; else { ty=J; break; } } } AnsiString filename; //得到请求的路径及文件名 filename=filemessage.SubString(tx,ty-tx); //设置默认的主页 if(filename=="/")filename="index.html"; filename=Edit2-$#@62;Text+filename; if((iFileHandle = FileOpen(filename, fmOpenRead))!=-1)//打开文件 { iFileLength = FileSeek(iFileHandle,0,2); FileSeek(iFileHandle,0,0); pszBuffer = new char[iFileLength+1]; iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength); FileClose(iFileHandle); //将文件传送到客户端 ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("HTTP/1.0 200 OK\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("MIME_version:1.0\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("Content_Type:text/html\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("Content_Length:\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("\n"); for (int i=0;i$#@60;iBytesRead;i++) ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText(pszBuffer[i]); delete[] pszBuffer; } else { //找不到路径时,传送出错页面 ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("HTTP/1.0 200 OK\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("MIME_version:1.0\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("Content_Type:text/html\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("Content_Length:\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;html$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;head$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;title$#@62;地址错误$#@60;/title$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;/head$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;body$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;center$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;h2$#@62;欢迎您使用FDL Web 服务$#@60;/h2$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;h1$#@62;刚才的地址没有找到!$#@60;/h1$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;h3$#@62;请检查您的URL$#@60;/h3$#@62;\n$#@60;br$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;br$#@62;\n2000年9月26日$#@60;br$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;br$#@62;$#@60;br$#@62;\n作者:符东亮$#@60;br$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;br$#@62;主页:"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;a href="http://fdlweb.8u8.com" target="_blank"$#@62;"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("http://fdlweb.8uu.com$#@60;/a$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;br$#@62;E-Mail:"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;a href=mailto:fdlweb@sina.com$#@62;"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("fdlweb@sina.com$#@60;/a$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;/center$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;/body$#@62;\n"); ServerSocket1-$#@62;Socket-$#@62;Connections[0]-$#@62;SendText("$#@60;/html$#@62;\n"); Memo1-$#@62;Lines-$#@62;Add("请求的文件不存在!"); } } catch(...)//处理错误 { Memo1-$#@62;Lines-$#@62;Add("连接出错!"); } Memo1-$#@62;Lines-$#@62;Add("断开 "+Socket-$#@62;RemoteAddress+" 的连接"); Socket-$#@62;Close();//断开当前的连接 Memo1-$#@62;Lines-$#@62;Add("开始新的侦听");
双击Button1,打开Button1的OnClick事件,然后加入下面这句代码:
Memo1-$#@62;Clear();//清除Memo的内容
同样,双击Button2,打开Button2的OnClick事件,加入下面的代码:
ServerSocket1-$#@62;Close(); Close();//退出
至此,一个简单但实用的器就完成了。按F9运行,打开IE,键入localhost或是主机名或主机IP地址回车,OK,主页跑出来了(若连接不到服务器,请安装TCP/IP协议)! 三、结束语 这个小小的Web服务器已能满足一般个人主页的调试使用,加入相应的代码可扩展其功能,变成FTP服务器、CGI服务器等。例如:在 Borland C++Builder 5 的源码例子中就有个CGI解释程序,将其加入,这个Web服务器就可以变成一个支持CGI的Web服务器。哈哈,以后请不用到处找CGI服务器了(怎么加,你慢慢研究吧)!
|