之前用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. iOS tableView移除某一行的分割线 让分割线宽度为整个cell的宽度

    移除tableViewCell中某一行的分割线 有2种方法 1. 移除系统的分割线,自己定义每行的分割线 self.tableView.separatorStyle = UITableViewCell ...

  2. /proc/kcore失效,调试其文件系统相关模块,使重新正常工作

    为分析内核,在有限的机器上用虚拟机装了CentOS.6.9.i386.minimal,重新编译了3.19.8内核并克隆.当使用/proc/kcore进行内核动态映像调试时,发现与kgdb远程调试端读到 ...

  3. 树莓派安装FLASK服务;并在端网页读取 GPIO状态和系统时间

    做过一些物联网的作品:因为不想一直做APP来控制,因为不能每个人都去下载你自己做的APP,浏览器大家都是有的:那么每个人通过浏览器WEB来访问我们服务器,岂不是很简单和方便,采用flask+pytho ...

  4. 开涛spring3(12.3) - 零配置 之 12.3 注解实现Bean定义

    12.3  注解实现Bean定义 12.3.1  概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[12.2注解实现Bean依赖注入]一节中介绍了通过注解来减少配置数量,但并没有完全 ...

  5. SQL SERVER大话存储结构(4)_复合索引与包含索引

              索引这块从存储结构来分,有2大类,聚集索引和非聚集索引,而非聚集索引在堆表或者在聚集索引表都会对其 键值有所影响,这块可以详细查看本系列第二篇文章:SQL SERVER大话存储结构 ...

  6. keyup实现在输入状态不发送搜索请求,停止输入后发送

    个人需求:通过keyup事件配合后台elasticsearch(弹性搜索),用户在输入状态不发送请求,等停止输入后发送请求. 这是个思考笔记,因为项目临时需要弹性搜索功能,所以临时想了这么个法子,方法 ...

  7. Ant + Jenkies +Tomcat 自动构建部署Web项目

    前言:博主资历尚浅,很多东西都还在刚起步学习的阶段,这几天开发任务比较轻,就在自己window系统下,模拟部署远程服务器,利用Jenkies + Ant + Tomcat 搭建了一个自动发布部署的环境 ...

  8. 在eclipse中输入.后提示解决

    1.调用系统自带的提示: 如果在eclipse中输入.后没有提示对应对象的属性和方法帮助列表,可以进行以下设置就可以了 eclipse -> Window-> Preferences-&g ...

  9. Python使用PyMysql操作数据库

    安装 pip install -U pymysql 连接数据库 连接数据库有两种不同的格式 直接使用参数 代码如下 import pymysql.cursors connection = pymysq ...

  10. JAVAEE学习——struts2_02:结果跳转方式、访问servletAPI方式、获得参数以及封装和练习:添加客户

    一.结果跳转方式 <action name="Demo1Action" class="cn.itheima.a_result.Demo1Action" m ...