当前位置:编程学习 > C#/ASP.NET >>

客户端软件通过代理用域名连接服务器端的问题!加急!拜谢!

环境介绍:
客户端软件安装在一台处在代理环境中的PC上,通过代理上互联网,代理协议是socks4 端口1080,也提供http协议代理,端口是808,没有用户名密码验证。代理服务器上设置了DNS服务器的地址。客户端软件通过socks4代理协议,是通过域名访问服务器端的,采用C#开发.net framwork 2.0。
问题描述:
如果在PC机的网络配置上的DNS服务器上填写了代理服务器的IP地址,那么就可以正确完成域名解析连上服务器端,如果PC上的DNS服务器配置上不填,那么就无法正确解析域名,提示an invalid IP address was specified。但通过IE浏览器(配置好了http代理的相关信息)就能访问互联网上的网站。想寻求解决办法,正常来说是不用配PC上的DNS服务器地址的,但不知道用哪个方法或函数,可以实现将域名发到代理服务器,让代理服务器连接DNS服务器来解析域名,将IP地址返回到PC的客户端软件上。
下面是我们使用的解析dns的代码,从完整代码中抽取出来了:
                string ipTemp = string.Empty;
                if (!IsCorrenctIP(m_ServerIP))
                {
                    ipTemp = Dns.GetHostEntry(m_ServerIP).AddressList[0].ToString();
                    m_ServerIP = ipTemp;
                }
                if (!IsCorrenctIP(m_AssemblyServerIP))
                {
                    ipTemp =Dns.GetHostEntry(m_AssemblyServerIP).AddressList[0].ToString();
                    m_AssemblyServerIP = ipTemp;
                }
                if (!IsCorrenctIP(m_DataDownloadServerIP))
                {
                    ipTemp=Dns.GetHostEntry(m_DataDownloadServerIP).AddressList[0].ToString();
                    m_DataDownloadServerIP = ipTemp;
                }
--------------------编程问答-------------------- 只会用代理,不懂原理. --------------------编程问答-------------------- 查了很多资料,关键找不到DNS这个类里面实现的底层里是怎样指定DNS服务器的,如果在本机的网络设置里面没有找到DNS服务器地址的话,怎么知道将这个域名解析请求发到代理服务器那边。 --------------------编程问答-------------------- 求求各位高手,帮帮忙亚! --------------------编程问答-------------------- 想到一个思路不知道对不对,

在我们的代码里,先进行了域名解析,然后再去执行和代理的连接动作,这样的话在域名解析时,是不是DNS类不知道该把域名解析请求先发到代理服务器上去,由代理服务器转发出去,因此应该先进性和代理服务器的连接,再进行域名解析,就像在网上找到的一段代码一样:
//************************************************
//
//重点在说明如何实现Socket5代理协议方式通讯
//http://blog.sina.com.cn/zhujiechang
//
//************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace sampleProxySocket
{
    class Program
    {
        // Declare the delegate prototype to send data back to the form
        static byte[] m_byBuff = new byte[256]; // Recieved data buffer
        static void Main(string[] args)
        {
            //重点来
            try
            {
                Console.WriteLine("socket5使用示例!");
                string proxyAddress = "192.168.1.2";
                int proxyPort = 1080;
                string destAddress = "www.csdn.net";
                int destPort = 80;


                IPEndPoint proxyIp = new IPEndPoint(IPAddress.Parse(proxyAddress), proxyPort);
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                socket.Connect(proxyIp);    //代理地址

                Shake_hands(socket);    //协议握手

                IPEndPoint destIp = new IPEndPoint(Dns.GetHostEntry(destAddress).AddressList[0], destPort);
                Protocol_Request(socket, destIp);   //协议请求

                //正常的请求
                SetupRecieveCallback(socket); 
                socket.Send(Encoding.ASCII.GetBytes(
                    string.Format("GET / HTTP/1.1 \r\nAccept: */* \r\nAccept-Language: zh-cn \r\nHost:{0}\r\n\r\n",
                    destAddress)));
                              
                
            } --------------------编程问答-------------------- 如果是HTTP代理的话 先进行域名解析  如果是TCP/IP的话 不用先解析吧! --------------------编程问答-------------------- 不解析的话,建立连接可以直接用域名么? --------------------编程问答-------------------- 又有一个解决思路就是因为在socks协议中可以直接发域名作为通过代理要访问的服务器的地址的,
代理协议内容如下:和代理握手完成之后,要进行一个请求连接,这个就是对远程服务器的连接,我们知道当前既然连接的是代理服务器,我们实际上发送数据的对象并不是它,也就是我们要告诉代理服务器去连接真实的某某,现在就是在做这一步了。
SOCKS请求的格式如下: 
VER CMD RSV ATYP DST.ADDR DST.PROT 
1 1 X’00’ 1 Variable 2 

其中
· VER 协议版本: X’05’
· CMD
· CONNECT:X’01’
· BIND:X’02’
· UDP ASSOCIATE:X’03’
· RSV 保留
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’'
· DST.ADDR 目的地址
· DST.PORT 以网络字节顺序出现的端口号
SOCKS服务器会根据源地址和目的地址来分析请求,然后根据请求类型返回一个或多个应答。
ATYP字段中描述了地址字段(DST.ADDR,BND.ADDR)所包含的地址类型:
· X'01'
基于IPV4的IP地址,4个字节长
· X'03'
基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字节。
· X'04'
基于IPV6的IP地址,16个字节长。
Variable表示该域的长度是可变的。

所以是不是可以将下面代码里面的data[3]赋值为03,然后直接用域名,向代理服务器发送向互联网上服务器的请求。
 if (proxyType == InnerCommEnum.ProxyType.PT_Socks4)//socks4代理服务
            {
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(m_proxyIP), Convert.ToInt32(m_proxyPost));
                //根据IP地址和端口号创建远程终结点
                EndPoint endPoint = (EndPoint)ipEndPoint;
                try
                {
                    m_ClientMainSocket.Connect(endPoint);
                    m_ClientMainSocket.ReceiveTimeout = 10000;
                    //连接请求
                    byte[] data = new byte[9];
                    data[0] = 4;//VER 协议版本
                    data[1] = 1;//CMD CONNECT:X’01’BIND:X’02’ UDP ASSOCIATE:X’03’
                   // data[2] = 0;//RSV 保留
                  //  data[3] = 1;//ATYP 后面的地址类型 IPV4:X’01’域名:X’03’ IPV6:X’04’'                    int length = 0;
                    byte[] buff = new byte[1024];
                    IPEndPoint destIP = new IPEndPoint(IPAddress.Parse(m_ServerIP), Convert.ToInt32(m_ServerPort));
                    
                    Array.Copy(BitConverter.GetBytes(
                    IPAddress.HostToNetworkOrder(destIP.Port)), 2, data, 2, 2);//以网络字节顺序出现的端口号                    
                    Array.Copy(destIP.Address.GetAddressBytes(), 0, data, 4, 4); //DST.ADDR 目的地址
                    m_ClientMainSocket.Send(data, SocketFlags.None); --------------------编程问答-------------------- 郁闷死了,用户那边用的是socks4,socks4不支持这种直接写域名访问的方式,大家有没有知道怎么发送域名解析的请求到socks4代理服务器上,然后取回解析好的ip的方法呢。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,