对于用WinInet开发Internet客户端应用指南感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍windows端开发,并为您提供关于.net–从webserver推送通知以winforms
对于用WinInet开发Internet客户端应用指南感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍windows端开发,并为您提供关于.net – 从webserver推送通知以winforms客户端应用程序、.NET的含义就是Internet,为什么国内做Web的公司大都不用,但国外的网站大都是.NET开发的?、asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序、asp.net – Intranet / Internet的Windows身份验证的有用信息。
本文目录一览:- 用WinInet开发Internet客户端应用指南(windows端开发)
- .net – 从webserver推送通知以winforms客户端应用程序
- .NET的含义就是Internet,为什么国内做Web的公司大都不用,但国外的网站大都是.NET开发的?
- asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序
- asp.net – Intranet / Internet的Windows身份验证
用WinInet开发Internet客户端应用指南(windows端开发)
概述
一个Internet客户端程序的目的是通过Internet协议如:HTTP、FTP等来存取网络数据源(服务器)的信息。客户端程序可以访问服务器获 得象天气预报,股票价格、重要新闻数据,甚至是与服务器交换信息。Internet客户端程序可以通过外部网络(Internet)或内部网络(一般为 Intranet)访问服务器。
为了开发Internet客户端程序。MFC类库提供了专门的 Win32 Internet 扩展接口,也就是WinInet。MFC将WinInet封装在一个标准的、易于使用的类集合中。在编写WinInet客户端程序时,你既可以直接调用 Win32函数,也可以使用WinInet类库。
Win32 Internet 扩展提供了对普通Internet协议的访问,这些协议包括:HTTP、FTP和Gopher。Gopher已经渐渐淡出。借助于WinInet编程接 口,开发人员不必去了解Winsock、TCP/IP和特定Internet协议的细节就可以编写出高水平的Internet客户端程序。WinInet 为所有几种协议(HTTP、FTP和Gopher)提供了统一的函数集,也就是Win32 API接口。利用这些统一的函数集,大大简化了针对HTTP、FTP等协议的编程,从而轻松地将Internet集成到自己的应用程序中。底层协议的转换 (如从FTP到HTTP)只要对源代码稍作修改就可以完成。
在Visual C++工程中提供有两种方式来使用WinInet。一种是直接调用Win32 Internet函数,另一种是使用WinInet类库。
MFC对WinInet的封装是通过提供三个由CStdioFile派生类实现的。这三个派生类是:CInternetFile、 CHttpFile 和 CGopherFile。由于Gopher协议已经很少使用,所以本文将不再对CGopherFile进行讨论。对开发人员来说,不管你以前是否用过 CStdioFile,WinInet都是很好理解并且易于使用的。它使得存取Internet数据易如反掌,使得Internet数据和本地数据的处理 一致透明,数据的存储位置已经不再重要。
MFC WinInet 类有如下优点:
- 缓冲器输入输出
- 数据的类型安全处理
- 许多函数的参数都是缺省值
- 对普通的Internet错误进行异常处理
- 自动清除打开的句柄和连接
使用 WinInet 提供的API函数,你可以:
- 通过HTTP协议下载HTML页,HTTP协议是专门用于在服务器和客户浏览器之间传输HTML页。
- 发送FTP请求上传或下载文件以及获取服务器的目录信息。通过匿名登陆下载文件便是FTP的典型应用。
- 其它基于HTTP、FTP协议的应用。
使用 WinInet 的一般流程为:
下表描述了一个Internet客户端程序实现的一般步骤:
实现 | 方法 |
建立一个连接 | 创建CInternetSession对象,它是WinInet Internet客户应用的前提条件 |
打开一个URL | 建立一个连接,调用CInternetSession::OpenURL 函数,返回一个只读资源对象 |
读取 URL 数据 | 打开一个URL,调用CInternetSession::QueryOption |
查询 Internet 选项设置 | 建立一个连接,调用CInternetFile::Read |
设置一个Internet选项 | 建立一个连接,调用CInternetSession::SetOption |
设置一个用状态信息调用的函数 | 建立一个连接,调用CInternetSession::EnableStatusCallback 重写CInternetSession::OnStatusCallback函数 |
关闭连接 | 用CInternetSession对象方法,清除打开的连接 |
为了创建Internet客户端程序,MFC提供了如下的C++类和全程函数:
C++类
CInternetSession (父类 CObject)
CInternetConnection (父类 CObject)
CFtpConnection
CGopherConnection
CHttpConnection
CInternetFile(父类 CStdioFile)
CGopherFile
CHttpFile
CFileFind(父类 CObject)
CFtpFileFind
CGopherFileFind
CGopherLocator(父类 CObject)
CInternetException(父类 CException)
全程函数
AfxParseURL
AfxGetInternetHandleType
AfxThrowInternetException
这些类和全程函数除CFileFind在AFX.H里声明之外,其余都在AFXINET.H文件里声明。它们对HTTP、FTP和Gopher等协议进行 了高度抽象,形成了一套高级API函数。 利用这些API可以快速直接地开发Internet应用。例如,连接到FTP服务器一般需要几个步骤,而且需要做一些底层处理。但使用上述的MFC类提供 的API,只需要对CInternetSession::GetFTPConnection进行一次调用,便可以轻松建立连接。
大家知道,每一个Internet应用其数据交换都是建立在Internet会话(Session)的基础之上的,MFC是通过 CInternetSession类对象来实现Internet会话的。用这个类不仅可以创建会话,而且可以创建几个并发的Internet会话。
为了与服务器进行通讯,除了要创建CInternetSession对象之外,还必须创建CInternetConnection对象,针对不同的协议,CInternetConnection对象有三种类型:
- CInternetSession::GetFtpConnection
- CInternetSession::GetHttpConnection
- CInternetSession::GetGopherConnection
这些函数调用并不会读写服务器上的文件。如果你想要读写数据,必须要打开文件才能操作。其处理流程应该是这样的:
- 首先创建 CInternetSession 对象实例
- 如 果创建的Session要读写文件,则必须创建 CInternetFile 对象实例(或者是它的子类CHttpFile、CGopherFile 对象实例)。其实,读取数据最容易的方式是调用 CInternetSession::OpenURL函数。 这个函数解析你提供的统一资源定位符(URL),然后打开与URL指定的服务器连接,同时返回一个只读的CInternetFile对象。 CInternetSession::OpenURL不针对特定的协议类型——不管是FTP还是HTTP都可以调用,它甚至可以处理本地文件,此时返回的 是CStdioFile,而不是CInternetFile。
- 如果创建的Session不读写文件,而是要实现其它的任务,如删除某个FTP目录下的文件等,则你不需要创建CInternetFile实例。
创建CInternetFile对象的方法有两种:
- 如果用CInternetSession::OpenURL建立与服务器的连接,调用返回CStdioFile。
- 如 果用CInternetSession::GetFtpConnection、GetGopherConnection或者 CHttpConnection::OpenRequest建立与服务器的连接,你必须调用相应的CFtpConnection::OpenFile、 CGopherConnection::OpenFile或者CHttpConnection::OpenRequest,返回的内容也与 CInternetFile、CGopherFile或者CHttpFile对应。
综上所述,实现Internet客户端应用的步骤因协议而异。要看你是创建基于OpenURL的一般Internet客户端应用,还是使用GetXXXConnection函数之一针对特定协议的Internet客户端应用。
在后继文章中我们将进一步讨论用WinInet实现Internet客户端应用程序的具体步骤和细节。
实现步骤
大家知道,每个Internet客户端程序都伴随有一定的目的行为,如读文件、写文件、删除文件等等。客户端的程序要实现这些行为的先决条件是建立 Internet连接。然后再根据不同的目的进行具体的操作。为了方便起见,下面这这些张表格针对不同的应用行为列出了所需要的具体操作。其中列出了一般 的Internet URL (FTP、或者 HTTP)客户端行为要实现某个目标所必须使用的方法。这张表格的内容来自MSDN。我对部分我认为重要的地方做了补充。
一个典型的Internet客户端程序的处理流程
目的 | 方法 | 结果 |
开始一个Internet session | 创建 CInternetSession 对象 | 初始化WinInet,并连接服务器 |
读取或设置 InternetQuery 选项 (如超时或重试次数) | 调用 CInternetSession::SetOption | 不成功返回FALSE |
建立回调函数监视session状态 | 调用CInternetSession::EnableStatusCallback 建立回调函数 |
CInternetSession::OnStatusCallback,重写OnStatusCallback,创建自己的回调例程 |
Internet服务器Intranet服务器或本地文件 | 调用 CInternetSession::OpenURL | 解析并打开到指定服务器的连接,返回CStdioFile(如果你传递的OpenURL是本地文件名)或CInternetFile对象,通过存取这个对象,获得服务器或文件的数据 |
读文件 | 调用 CInternetFile::Read | 用你提供的Buffer读指定的字节数 |
异常处理 | 在 CInternetException 类中处理 | 处理所有普通的 Internet 异常类型 |
结束 Internet session 处理 | CInternetSession对象 | 自动清除打开的句柄的连接 |
典型的 FTP 客户端程序实现的一般步骤
目的 | 方法 | 结果 |
开始一个FTP会话,建立一个FTP连接 | 创建一个CInternetSession对象,调用CInternetSession::GetFtpConnection | 初始化WinInet 并联接服务器 |
连接到一个FTP Server | 用CInternetSession::GetFtpConnection | 返回一个CFtpConnection对象 |
CD到 FTP 服务器的一个新目录 | 用CFtpConnection::SetCurrentDirectory | CD到FTP服务器的一个 新目录 |
Find 第一个FTP目录中的文件 | 创建一个CFtpFileFind对象,调用CFtpFileFind::FindFile,OpenURL函数返回一个只读资源对象;调用CFtpFileFind::FindFile | Find第一个文件,如果文件每找到返回FALSE |
枚举所有可获得的资源,Find下一个FTP目录中的文件 | Find下一个资源,调用CFtpFileFind::FindNextFile直到返回FALSE。 | Find下一个文件 如果文件没找到返回FALSE |
打开FindFile或FindNextFile找到的文件(用于读写) | 调用CFtpConnection::OpenFile,参数为FindFile或FindNextFile返回的文件名 ,创建并打开一个CInternetFile对象 | 打开FindFile或FindNextFile找到的文件(用于读写),返回一个CInternetFile对象 |
读写文件 | 以读方式打开FTP文件,用CInternetFile::Read | 使用你指定的缓冲读 指定的字节数 |
写FTP文件 | 以写方式打开FTP文件,调用CInternetFile::Write,重写CInternetSession::OnStatusCallback | 使用你指定的缓冲写 指定的字节数 |
改变客户端在服务器上的目录 | 调用CFtpConnection::SetCurrentDirectory | 进入新的目录 |
获取客户端在服务器上的当前目录 | 调用CFtpConnection::GetCurrentDirectory | 获取目录信息 |
异常处理 | 用CInternetException类 | 处理所有普通的Internet异常类型 |
结束FTP session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 |
一个典型的删除文件的FTP客户端应用要实现的一般步骤
目的 | 方法 | 结果 |
开始一个FTP session | 创建一个CInternetSession对象 | 初始化WinInet 并联接服务器 |
连接到一个FTP Server | 用CInternetSession::GetFtpConnection | 返回一个CFtpConnection对象 |
检查FTP目录是否正确 | 用CFtpConnection::GetCurrentDirectory或CFtpConnection::GetCurrentDirectoryAsURL | 返回目录名字 服务器目录或返回目录的URL |
CD(改变目录)到 FTP 服务器的一个新目录 | 用CFtpConnection::SetCurrentDirectory | CD到FTP服务器的一个 新目录 |
Find 第一个FTP目录中的文件 | 用CFtpFileFind::FindFile | Find第一个文件,如果文件每找到返回FALSE |
Find 下一个FTP目录中的文件 | 用CFtpFileFind::FindNextFile | Find下一个文件 如果文件没找到返回FALSE |
删除FindFile或FindNextFile找到的文件 | 用CFtpConnection::Remove用FindFile或FindNextFile返回的文件名 | 删除FindFile或FindNextFile 找到的文件 |
异常处理 | 用CInternetException类 | 处理所有普通的Internet异常类型 |
结束FTP session | 处理CInternetSession对象 | 自动清除打开的句柄的连接 |
实现一个典型的 HTTP 客户端应用程序的一般步骤
目的 | 方法 | 结果 |
开始HTTP会话,建立HTTP连接 | 创建 CInternetSession对象,调用CInternetSession::GetHttpConnection 创建CHttpConnection对象 |
初始化WinInet并联接服务器,返回一个CHttpConnection对象 |
创建一个 HTTP 请求 | 调用CHttpConnection::OpenRequest 创建一个CHttpFile对象; |
返回一个CHttpFile对象 |
发送一个HTTP 请求 | 用CHttpFile::AddRequestHeaders 并且用CHttpFile::SendRequest | Find一个文件 如果文件没找到返回FALSE |
读文件 | 调用CInternetFile::Read | 使用你提供的缓冲读指定的字节 |
获取HTTP请求信息 | 调用CHttpFile::QueryInfo | 从服务器获取HTTP请求头信息 |
异常处理 | 利用CInternetException类 | 处理所有普通的Internet异常类型 |
结束 HTTP 会话 | 处理CInternetSession对象 | 自动清除打开的句柄的连接 |
由于时间关系,我没有写本文的例子代码。不过MSDN里有两个简单的例子可以参考,一个是FTPTREE,另一个是TEAR。此外,也可以用“WinInet”作为关键字在google里搜一下也能找到一些使用MFC WinInet的技术信息。
.net – 从webserver推送通知以winforms客户端应用程序
我已经看过像node.js这样的东西,一些例子展示了如何将通知推送到网站而不是客户端.我不知道这些技术是否可以用于我想要的东西.你们有没有这方面的经验?
谢谢,
解决方法
该站点上的示例使用WPF但您可以使用WinForms完全相同.
这是SignalR的overview.它允许您从客户端上的服务器和服务器上的客户端调用方法.正如您在这些网站上看到的那样,SignalR主要是为Web应用程序构建的,但对于标准的Winforms客户端使用它是没有问题的.
.NET的含义就是Internet,为什么国内做Web的公司大都不用,但国外的网站大都是.NET开发的?
.NET就是互联网,听说国外大部分网站都是用.NET开发的,为什么国内互联网公司的web网站大都不用.NET?这是否表示国内还是很落后的?
asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序
一. 概述
本篇探讨使用"基于浏览器的JavaScript客户端应用程序"。与上篇实现功能一样,只不过这篇使用JavaScript作为客户端程序,而非core mvc的后台代码HttpClient实现。 功能一样:用户首先要登录IdentityServer站点,再使用IdentityServer发出的访问令牌调用Web API,可以注销IdentityServer站点下登录的用户,清除cookie中的令牌信息。所有这些都将来自浏览器中运行的JavaScript。
此示例还是三个项目:
IdentityServer令牌服务项目 http://localhost:5000
API资源项目 http://localhost:5001
JavaScript客户端项目 http://localhost:5003
开源Github
二. IdentityServer项目
1.1 定义客户端配置
Config.cs中,定义客户端,使用code 授权码模式,即先登录获取code,再获取token。项目其它处代码不变。
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
//授权码模式
AllowedGrantTypes = GrantTypes.Code,
//基于授权代码的令牌是否需要验证密钥,默认为false
RequirePkce = true,
//令牌端点请求令牌时不需要客户端密钥
RequireClientSecret = false,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
//指定跨域请求,让IdentityServer接受这个指定网站的认证请求。
AllowedCorsOrigins = { "http://localhost:5003" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
};
}
三. API项目
在Web API项目中配置 跨域资源共享CORS。这将允许从http:// localhost:5003 (javascript站点) 到http:// localhost:5001 (API站点) 进行Ajax调用(跨域)。项目其它处代码不变。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "api1";
});
//添加Cors服务
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:5003")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
}
public void Configure(IApplicationBuilder app)
{
//添加管道
app.UseCors("default");
app.UseAuthentication();
app.UseMvc();
}
四. JavaScript客户端项目
在项目中,所有代码都在wwwroot下,没有涉及到服务端代码,可以完全不用core程序来调用。目录如下所示:
其中添加了两个html 页(index.html, callback.html),一个app.js文件,这些属于自定义文件。oidc-client.js是核心库。
4.1 index页面
用于调用登录、注销、和api。引用了oidc-client.js和app.js
<body>
<button id="login">Login</button>
<button id="api">Call API</button>
<button id="logout">Logout</button>
<pre id="results"></pre>
<script src="oidc-client.js"></script>
<script src="app.js"></script>
</body>
4.2 app.js
是应用程序的主要代码,包括:登录、Api请求,注销。配置与服务端代码差不多,如下所示:
/// <reference path="oidc-client.js" />
//消息填充
function log() {
document.getElementById(''results'').innerText = '''';
Array.prototype.forEach.call(arguments, function (msg) {
if (msg instanceof Error) {
msg = "Error: " + msg.message;
}
else if (typeof msg !== ''string'') {
msg = JSON.stringify(msg, null, 2);
}
document.getElementById(''results'').innerHTML += msg + ''\r\n'';
});
}
document.getElementById("login").addEventListener("click", login, false);
document.getElementById("api").addEventListener("click", api, false);
document.getElementById("logout").addEventListener("click", logout, false);
var config = {
authority: "http://localhost:5000",
client_id: "js",
redirect_uri: "http://localhost:5003/callback.html",
response_type: "code",
scope:"openid profile api1",
post_logout_redirect_uri : "http://localhost:5003/index.html",
};
//UserManager类
var mgr = new Oidc.UserManager(config);
//用户是否登录到JavaScript应用程序
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
}
});
//登录
function login() {
mgr.signinRedirect();
}
//跨域请求api
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
}
//注销
function logout() {
mgr.signoutRedirect();
}
4.3 callback.html
用于完成与IdentityServer的OpenID Connect协议登录握手。对应app.js中config对象下的redirect_uri: "http://localhost:5003/callback.html"。登录完成后,我们可以将用户重定向回主index.html页面。添加此代码以完成登录过程
<body>
<script src="oidc-client.js"></script>
<script>
new Oidc.UserManager({ response_mode: "query" }).signinRedirectCallback().then(function () {
window.location = "index.html";
}).catch(function (e) {
console.error(e);
});
</script>
</body>
五 测试
(1) 启动IdentityServer程序http://localhost:5000
(2) 启动API程序http://localhost:5001。这二个程序属于服务端
(3) 启动javascriptClient程序 http://localhost:5003
(4) 用户点击login,开始握手授权,重定向到IdentityServer站点的登录页
(5) 输入用户的用户名和密码,登录成功。跳转到IdentityServer站点consent同意页面
(6) 点击 yes allow后,跳回到客户端站点http://localhost:5003/index.html,完成了交互式身份认证。
(7) 调用点击Call API按钮,获取访问令牌,请求受保护的api资源。调用CallAPI 时,是访问的api站点http://localhost:5001/identity。
参考文献
添加JavaScript客户端
原文出处:https://www.cnblogs.com/MrHSR/p/10735033.html
asp.net – Intranet / Internet的Windows身份验证
@H_301_0@我需要找到一种方法,不能为Intranet用户提示Windows身份验证模式,并为Internet用户提示Windows身份验证模式.
我该怎么做?
解决方法
首先一些链接:
> Technet作为一篇关于Windows Authentication in IIS here的文章
> MSDN告诉你how to use Windows Authentication with ASP.NET 2.0 applications here
但请注意以下事项:
如果满足以下条件,单点登录(SSO)(即访问应用程序而不提供用户名和密码)将会发生:
>客户端计算机和服务器是同一Active Directory域的一部分.
>客户端计算机上的用户会话是AD域中的用户.
>客户端计算机可以访问域服务器(即负责用户登录的服务器)
>浏览器是Internet Explorer.
>使用的URL指向服务器的FQDN(即http://SERVERNAME.DOMAIN.NAME/不仅仅是http://SERVERNAME/
>如果您使用冒号,授权用户必须具有对应用程序目录的读取访问权限.应用程序将基本上运行他们的凭据. (MSDN article更多细节)
在任何其他情况下,用户将被提示为Active Directory域中的帐户提供凭据(用户名和密码).所以用户从互联网访问您的网络服务器会得到一个弹出窗口,要求他们提供一个用户名和密码.
请注意,对于不使用单一登录(用户被提示输入用户名和密码)的用户,HTTP身份验证模式很可能是BASIC,这意味着任何可以拦截该连接的人都可以看到要交换的用户名和密码.如果你使用这种技术使得客户端和服务器之间的连接被加密(HTTPS或者也许是VPN).
今天关于用WinInet开发Internet客户端应用指南和windows端开发的分享就到这里,希望大家有所收获,若想了解更多关于.net – 从webserver推送通知以winforms客户端应用程序、.NET的含义就是Internet,为什么国内做Web的公司大都不用,但国外的网站大都是.NET开发的?、asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序、asp.net – Intranet / Internet的Windows身份验证等相关知识,可以在本站进行查询。
本文标签: