之前用VBS写过一个,效率和支持比较low,这次闲着没事用VB重写了一次。

当前的实现版本仅支持静态文件的访问(*.html之类),支持访问方式为GET,HTTP状态支持200和404。

两个文件,一个是定义了常用到的函数的模块tools.bas

 'tools.bas
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Const WEB_ROOT As String = "c:\web"
Public req_types As Object Public Function GetHeader(ByVal data As String, ByVal idex As Integer) As Object
'head [dictionary objet]:
' Request, [dictionary objet] <Method|File|Protocol>
' Host, [string]
' Accept-Language, [string]
' *etc
Set head = CreateObject("scripting.dictionary")
Set rqst = CreateObject("scripting.dictionary")
Call head.Add("RemoteHost", Form1.SckHandler(idex).RemoteHostIP)
Call head.Add("RemotePort", Form1.SckHandler(idex).RemotePort)
temp = Split(data, vbCrLf)
'request's method, file and protocol
rmfp = Split(temp(), " ")
Call rqst.Add("Method", rmfp())
Call rqst.Add("File", rmfp())
Call rqst.Add("Protocol", rmfp())
Call head.Add("Request", rqst)
For idex = To UBound(temp)
If temp(idex) <> "" Then
prop = Split(temp(idex), ": ")
Call head.Add(prop(), prop())
End If
Next
Set GetHeader = head
End Function Public Sub Sleep(ByVal dwDelay As Long)
limt = GetTickCount() + dwDelay
Do While GetTickCount < limt
DoEvents
Loop
End Sub Function URLDecode(ByVal url As String) As String
'using the function [decodeURI] from js
Set js = CreateObject("scriptcontrol")
js.language = "javascript"
URLDecode = js.eval("decodeURI('" & url & "')")
Set js = Nothing
End Function Public Function GetGMTDate() As String
Dim WEEKDAYS
Dim MONTHS
Dim DEFAULT_PAGE WEEKDAYS = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
MONTHS = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec")
DEFAULT_PAGE = Array("index.html", "index.htm", "main.html", "main.htm")
date_ = DateAdd("h", -, Now())
weekday_ = WEEKDAYS(Weekday(date_) - )
month_ = MONTHS(Month(date_) - )
day_ = Day(date_): year_ = Year(date_)
time_ = Right(date_, )
If Hour(time_) < Then time_ = "" & time_
GetGMTDate = weekday_ & ", " & day_ & _
" " & month_ & " " & year_ & _
" " & time_ & " GMT"
End Function Public Function url2file(ByVal url As String) As String
file = URLDecode(url)
'默认文件为 index.html
If file = "/" Then file = "/index.html"
file = Replace(file, "/", "\")
file = WEB_ROOT & file
url2file = file
End Function Public Function GetBytes(ByVal file As String, ByRef byts() As Byte) As Long
'not supported big file which size>2G
fnum = FreeFile()
Open file For Binary Access Read As #fnum
size = LOF(fnum)
If size = Then
byts = vbCrLf
Else
ReDim byts(size - ) As Byte
Get #fnum, , byts
End If
Close #fnum
GetBytes = size
End Function Public Function SetResponseHeader(ByVal file As String, ByVal size As Long) As String
'get the content-type from extension,
' if file has not ext, then set it to .*
If InStr(file, ".") = Then file = file & ".*"
ext = "." & Split(file, ".")()
ftype = req_types(ext)
header = "HTTP/1.1 200 OK" & vbCrLf & _
"Server: http-vb/0.1 vb/6.0" & vbCrLf & _
"Date: " & GetGMTDate() & vbCrLf & _
"Content-Type: " & ftype & vbCrLf & _
"Content-Length: " & size & vbCrLf & vbCrLf
SetResponseHeader = header
End Function

然后是窗体部分,目前日志全部都用的Debug打印的,因此就没专门来写日志输出:

 'code by lichmama
'winsock 状态常数
Private Enum WINSOCK_STATE_ENUM
sckClosed = '关闭状态
sckOpen = '打开状态
sckListening = '侦听状态
sckConnectionPending = '连接挂起
sckResolvingHost = '解析域名
sckHostResolved = '已识别主机
sckConnecting = '正在连接
sckConnected = '已连接
sckClosing = '同级人员正在关闭连接
sckError = '错误
End Enum Private Sub Command1_Click()
'启动监听
Call Winsock1.Listen
Me.Caption = "HTTP-SERVER/VB: HTTP服务启动,监听端口80"
End Sub Private Sub Command2_Click()
'关闭监听
Call Winsock1.Close
For i = To
Call SckHandler(i).Close
Next
Me.Caption = "HTTP-SERVER/VB: HTTP服务已停止"
End Sub Private Sub Form_Load()
'当前支持的文件类型
Set req_types = CreateObject("scripting.dictionary")
Call req_types.Add(".html", "text/html")
Call req_types.Add(".htm", "text/html")
Call req_types.Add(".xml", "text/xml")
Call req_types.Add(".js", "application/x-javascript")
Call req_types.Add(".css", "text/css")
Call req_types.Add(".txt", "text/plain")
Call req_types.Add(".jpg", "image/jpeg")
Call req_types.Add(".png", "image/image/png")
Call req_types.Add(".gif", "image/image/gif")
Call req_types.Add(".ico", "image/image/x-icon")
Call req_types.Add(".bmp", "application/x-bmp")
Call req_types.Add(".*", "application/octet-stream") For i = To
Call Load(SckHandler(i))
With SckHandler(i)
.Protocol = sckTCPProtocol
.LocalPort =
.Close
End With
Next With Winsock1
.Protocol = sckTCPProtocol
.Bind , "0.0.0.0"
.Close
End With
End Sub Private Sub Form_Unload(Cancel As Integer)
Winsock1.Close
For i = To
SckHandler(i).Close
Next
End Sub Private Sub SckHandler_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim buff As String
Call SckHandler(Index).GetData(buff, vbString, bytesTotal)
Call Handle_Request(buff, Index)
End Sub Private Sub SckHandler_SendComplete(Index As Integer)
Call SckHandler(Index).Close
End Sub Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
HANDLER_ENTRANCE_:
For i = To
If SckHandler(i).State <> sckConnected And _
SckHandler(i).State <> sckConnecting And _
SckHandler(i).State <> sckClosing Then
Call SckHandler(i).Accept(requestID)
Exit Sub
End If
Next
'如果未找到空闲的handler,等待100ms后,继续寻找
Call Sleep(): GoTo HANDLER_ENTRANCE_
End Sub Private Sub Handle_Request(ByVal req As String, ByVal HandlerId As Integer)
Dim byts() As Byte
Set head = GetHeader(req, HandlerId) file = url2file(head("Request")("File"))
fnme = Dir(file)
If fnme <> "" Then
size = GetBytes(file, byts)
SckHandler(HandlerId).SendData SetResponseHeader(file, size)
SckHandler(HandlerId).SendData byts
Erase byts
Debug.Print "[HTTP-VB]: " & head("Request")("Method") & " " & _
head("Request")("File") & " " & _
head("Request")("Protocol"); " " & _
head("RemoteHost") & ":" & head("RemotePort") & " " & _
"-- 200 OK"
Else
page404 = "<!DOCTYPE html><html><head><title>404错误 - HTTP_VB(@lichmama)</title><body><br><p style='text-align:center;font-family:consolas'>""don't busy on trying, maybe you just took a wrong way of opening.""<br> -- kindly tip from <i style='color:red;font-size:32px'>404</i></p></body></head></html>"
SckHandler(HandlerId).SendData "HTTP/1.1 404 NOT FOUND" & vbCrLf & _
"Server: http-vb/0.1 vb/6.0" & vbCrLf & _
"Date: " & GetGMTDate() & vbCrLf & _
"Content-Length: " & Len(page404) & vbCrLf & vbCrLf
SckHandler(HandlerId).SendData page404
Debug.Print "[HTTP-VB]: " & head("Request")("Method") & " " & _
head("Request")("File") & " " & _
head("Request")("Protocol"); " " & _
head("RemoteHost") & ":" & head("RemotePort") & " " & _
"-- 404 NOT FOUND"
End If Set head("Request") = Nothing
Set head = Nothing
End Sub

最后上两张图,后台:

404:

正常访问:

VB6之HTTP服务器的实现的更多相关文章

  1. VB6之HTTP服务器的实现(二)

    接上篇,这次做了小小的改动和提升.增加了对POST的支持和对其他方法(GET和POST之外的)选择405回复.另外,增加了对CGI的支持,目前可以使用C语言来写(是不是好蠢的赶脚).相对于上篇,整体做 ...

  2. 【VB6】vbRichClient5.cWebServer实现一个简单web服务器

    Option Explicit Private WithEvents k As vbRichClient5.cWebServer Private Sub Command1_Click() Set k ...

  3. 使用VB6制作RTD函数

    以前模仿大神在vs里使用c#实现RTD函数功能.(真是很生僻的东东啊)C#制作RTD参考:大神博客跳转.最近想VB里能不能做?就试着做了做,好像基本成了,整套代码有些毛病,勉强能算个样子,暂时不打算再 ...

  4. 链接服务器"(null)"的 OLE DB 访问接口 "Microsoft.Jet.OLEDB.4.0" 返回了消息 "未指定的错误"。[手稿]

    消息 7302,级别 16,状态 1,第 1 行 无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.JET.OLEDB.4.0&qu ...

  5. 【VB/.NET】Converting VB6 to VB.NET 【Part II】【之四】

    第四部分 原文 DLLs, DAO, RDO, ADO, and AD.NET; the History of VB DBs In the early versions of VB, there we ...

  6. 前端向服务器请求数据并渲染的方式(ajax/jQuery/axios/vue)

    原理: jQuery的ajax请求:complete函数一般无论服务器有无数据返回都会显示(成功或者失败都显示数据): return result

  7. 如何在同一台服务器上部署两个tomcat

    因为测试的需要,有时我们必须在同一个服务器上部署两个tomcat,然后去做应用的部署,那么很多同学可能会觉得比较为难,找的资料也比较的不齐全,那么今天华华就来给大家讲讲如何部署2个tomcat,并能够 ...

  8. VB6 如何连接MYSQL数据库

    1 从官网下载MYSQL的ODBC,选择与自己操作系统对应的版本(前提是你安装了MYSQL) http://dev.mysql.com/downloads/connector/odbc/   2 安装 ...

  9. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

随机推荐

  1. UITextView 实现链接点击事件

    UILabel通过富文本可以实现图文混排,但是想要实现文字的点击效果好像不容易实现,这里有2种方法可以达到效果 YYLabel -->YYText框架 参考我之前的博客:http://www.c ...

  2. Calendar使用

    1简单例子 package com.kungeek.tip; import java.text.SimpleDateFormat; import java.util.Calendar; import ...

  3. javaWeb学习总结(7)-会话之session技术

    什么是Session 使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度. Session技 ...

  4. git底层原理(二)

    git对象模型 在git系统中有四种类型的对象,所有的Git操作都是基于这四种类型的对象:"blob":这种对象用来保存文件的内容."tree":可以理解成一个 ...

  5. PHP接口学习

    接口:不同类的共同行为进行定义,然后在不同类中实现不同的功能. 接口的具体语法: 接口是零件可以用多个零件组成一个新东西: 接口本身是抽象的,内部申明的方法也是抽象的: 不用加abstract 一个类 ...

  6. js 实现倒计时效果

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. javascript痛点之二作用域链

    1.执行环境(执行上下文) 先看段代码 var a = 10; var b = 20; function cc(){ var c = 30; alert("b="+b); } cc ...

  8. js for循环 等腰三角形demo

    <script> for(var i=1;i<10;i++){ for(var j=1;j<10-i;j++){document.write(" ")} f ...

  9. DELPHI XE8 远程调试

    最近公司项目遇到问题需要远程调试搜索了一下怎么用 发现网上能找到最新的是XE2上的说明现在已经有一些不同了 按照上面的方法不能调试成功 经过测试XE8的方法如下:1.项目编译设置:2.在被调试电脑上运 ...

  10. 【基础】C#异常处理的总结

    一.异常处理的理解? 异常处理是指程序在运行过程中,发生错误会导致程序退出,这种错误,就叫做异常. 因此处理这种错误,就称为异常处理. 二.异常处理如何操作? C# 异常处理时建立在四个关键词之上的: ...