C#开发可穿透代理服务器的WinForm应用 [转]
http://blog.csdn.net/redbirdli/
企业上网一般都是通过网关服务器,部分非自动的代理服务器需要手工设置(就像IE需要在连接-局域网设置-代理器中的那样),前段为企业开发了一个需要远程访问HTTP服务器的应用,发现在手动代理的网络环境下,会在运行时WebRequest试图通过GetResponse获取Response对象时抛出:error: 远程服务器返回错误: (407) 需要代理身份验证。 的错误,其实就是因为网络代理服务器验证失败被拒绝的缘故。
前段碰到这个问题,苦于自己没有这样的网络环境,最近正好在客户单位干活,就是用了代理服务器,所以就花了一会儿时间搞出来了,其实很简单:
1.获取IE当前缺省的代理服务器信息(物理上其实存储在HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\的ProxyEnable和ProxyServer),地址和端口号可以获取,但用户名和密码还是必须通过设置来获取
2.设置WebRequest的Proxy属性,绑定到有效的Proxy对象
我自己封装了一个方法,无论是直接连接还是通过代理服务器都可以自适应:
public static void ProxySetting(WebRequest request)
{
WebProxy proxy = WebProxy.GetDefaultProxy();//获取IE缺省设置
{
WebProxy proxy = WebProxy.GetDefaultProxy();//获取IE缺省设置
//如果缺省设置为空,则有可能是根本不需要代理服务器,如果此时配置文件中也未配置则认为不需Proxy
if (proxy.Address == null && Sys.ProxyAddress != null && Sys.ProxyAddress != "")
proxy.Address = new Uri(Sys.ProxyAddress);//按配置文件创建Proxy 地置
if (proxy.Address == null && Sys.ProxyAddress != null && Sys.ProxyAddress != "")
proxy.Address = new Uri(Sys.ProxyAddress);//按配置文件创建Proxy 地置
if (proxy.Address != null)//如果地址为空,则不需要代理服务器
{
proxy.Credentials = new NetworkCredential(Sys.ProxyUser, Sys.ProxyKey);//从配置封装参数中创建
request.Proxy = proxy;//赋予 request.Proxy
}
{
proxy.Credentials = new NetworkCredential(Sys.ProxyUser, Sys.ProxyKey);//从配置封装参数中创建
request.Proxy = proxy;//赋予 request.Proxy
}
}
调用:
request = (HttpWebRequest)WebRequest.Create(http://abc.com/def.xml);
ProxySetting(request);//加在获取响应前
request.GetResponse();
配置文件可能如下,读回后被Sys封装:
<add key="ProxyAddress" value="" />
<add key="ProxyUser" value="msuser" />
<add key="ProxyKey" value="hello" />
<add key="ProxyUser" value="msuser" />
<add key="ProxyKey" value="hello" />
OK了,现在你的程序就可以穿透设有代理服务器的局域网了
另外,如果需要用到类似XmlDocument直接加载远程XML文件的时间也会出现这样的问题,解决办法也很简单,多写一个方法改用WebRequest获取远程XML,再将Load方法改为LoadXml的装入String就可以了,如下:
public static XmlDocument loadXMLDocument(string FileNameOrUrl)
{
XmlDocument doc = null;
try
{
doc = new XmlDocument();
// doc.Load( FileNameOrUrl);
doc.LoadXml(GetWeb(FileNameOrUrl));//改为由WebRequest取回后载入XMLString
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
Pub.logError(e);
doc = null;
}
return doc;
}
public static string GetWeb(string Url)
{
HttpWebRequest request ;
HttpWebResponse response=null;
StreamReader htmlStream =null;
Stream stream=null;
string html="";
int i=0;
do
{
request=(HttpWebRequest )WebRequest.Create(Url);
ProxySetting(request);//检查代理设置
try
{
response = (HttpWebResponse)request.GetResponse();
break;
}
catch
{
request=null;
}
}
while(i++ <3);
if (response==null) return "";
if (request.HaveResponse)
{
try
{
stream = response.GetResponseStream();
htmlStream = new StreamReader(stream,System.Text.Encoding.Default,true);
html=htmlStream.ReadToEnd();
}
catch
{}
finally
{
response.Close();
htmlStream.Close();
stream.Close();
}
}
return html;
}