之前用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. swift学习 - collectionView

    swift CollectionView学习 效果图: 源码: ContModel.swift import UIKit class ContModel: NSObject { var title:S ...

  2. 项目管理之 Objective-C 编码规范

    目录: 一.格式化代码 二.命名 命名要求 1. 类的命名: 规则: 大驼峰命名法,每个单词的首字母都采用大写字母.一般添加业务前缀.后缀一般是当前类的种类. ViewController:后缀:Vi ...

  3. 记一次利用AutoMapper优化项目中数据层到业务层的数据传递过程。

    目前项目中获取到DataSet数据后用下面这种方式复制数据. List<AgreementDoc> list = new List<AgreementDoc>(); ].Row ...

  4. HTML标签类型及特点

    关键词:块级元素  行级元素 行内块元素   一. 概述           HTML(Hyper Text Markup Language )作为一种标记语言,网页所有的内容均书写在标签内部,标签是 ...

  5. 【原创】Ajax的用法总结

    一.什么是Ajax Ajax英文全称为“ Asynchr JavsScript and XML”(异步的JavaScript和XML),是一种创建 交互式网页的开发技术. 二.Ajax技术的核心 Aj ...

  6. MVC分层含义与开发方式

    真正的服务层是面向数据的,假想一切数据都是从参数获得 控制层是接受页面层数据,再传给服务层,然后将结果返回给页面层的(客户) 页面层是提交格式化的数据的(容易小混乱,无格式,所以要格式化,可以在中间加 ...

  7. 微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  8. 我的第一个jQuery插件--表格隔行变色

    虽然网上有大量的插件供我们去使用,但不一定有一款适合你的,必要的时候还是要自己动手去敲的.下面,开始我的第一个插件... 参考<锋利的JQuery>,JQuery为开发插件增设了俩个方法: ...

  9. JDK和Tomcat的简单配置(菜鸟巧记一)

    JDK和Tomcat的配置 1.先好安装JDK 1.1先到oracle官网下载合适自己的JDK 地址http://www.oracle.com/technetwork/java/javase/down ...

  10. 用PHP和Ajax进行前后台数据交互——以用户登录为例

    很多网站中都有用户登录系统,要完成用户的注册和登陆,就一定要用到前后台的数据交互.在这里以简单的用户注册和登陆为例介绍一下前后台交互的大致流程. 首先,我们来做一个简单的登陆界面. 这里为了方便我使用 ...