关于SOCKS5通信的客户端问题

weixin_42298060 2018-08-21 06:12:18
我的编译环境是win10+visual studio 2015
客户端是用C#写的控制台程序
我调试的时候是在本机上架设了一个代理服务器,所以代理端地址是192.168.0.109:1002
先上代码

/* ***********************************************
* Author : CYhyq
* Email : 421160052@qq.com
* DateTime : 2018-08-21 15:41:52
* Description : 核心代码 的摘要说明
*
* ***********************************************/
using System;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace Socks5.proxy
{
class Program
{
static void Main(string[] args)
{
Proxy proxy = new Proxy();
proxy.SendFirstMessage();
Console.WriteLine("如果要停止服务,请按回车键!!");
Console.ReadLine();
}
public class Proxy
{
static string proxyIP = "192.168.0.109";
static int proxyPort = 1002;
IPEndPoint proxyEndPoint = new IPEndPoint(IPAddress.Parse(proxyIP), proxyPort); //代理IP
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket receiveSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
byte[] request = new byte[1000]; //请求信息
byte[] sreceive = new byte[10000]; //返回消息
string userName = "xxxx"; //账户
string password = "xxxx"; //密码
byte[] rawBytes = new byte[1024]; //转换容器
int nIndex = 0; //下标
string destAddress = "52.235.21.1"; //目的地网址
static int dest_port = 13307; //目的端口
static byte[] result = new byte[1024]; //结果集
static int port; //转换的端口
StringBuilder sb = new StringBuilder(); //接收数据的结果
static string Result; //结果--字符串
public void SendFirstMessage()
{
// open a TCP connection to SOCKS server...
s.Connect(proxyEndPoint);
//第一次发送信息
nIndex = 0;
request[nIndex++] = 0x05; // Version 5.
request[nIndex++] = 0x01; // METHOD.
request[nIndex++] = 0x02; // USERNAME/PASSWORD
s.Send(request, 3, SocketFlags.None);
int a = s.Receive(sreceive, sreceive.Length, SocketFlags.None);
//Username / Password Authentication protocol

//第二次发送验证消息
byte[] request1 = new byte[userName.Length+ password.Length+3];
nIndex = 0;
request1[nIndex++] = 0x01; // Version 5.
// add user name Length
request1[nIndex++] = (byte)userName.Length;
rawBytes = Encoding.Default.GetBytes(userName);
// 账户本身
rawBytes.CopyTo(request1, nIndex);
nIndex += (ushort)rawBytes.Length;
// add password Length
request1[nIndex++] = (byte)password.Length;
rawBytes = Encoding.Default.GetBytes(password);
// 密码本身
rawBytes.CopyTo(request1, nIndex);
nIndex += (ushort)rawBytes.Length;
// Send the Username/Password request
s.Send(request1, request1.Length, SocketFlags.None);
a = s.Receive(sreceive, sreceive.Length, SocketFlags.None);
if (sreceive[1] !=0)
{
Console.WriteLine("代理服务器验证失败。");
}
else
{
Console.WriteLine("代理服务器验证成功。");
//继续发送请求
// Send connect request now...
nIndex = 0;

string [] IP_Array= destAddress.Split('.');
request[nIndex++] = 0x05; // version 5.
request[nIndex++] = 0x01; // 1 = connect. 2 = bind . 3 = UDP
request[nIndex++] = 0x00; // Reserve = must be 0x00 此功能为保留功能
//request[nIndex++] = 0x04; // ATYP=IPV6
request[nIndex++] = 0x01; // ATYP=IPV4

//服务器IP*
request[nIndex++] = Convert.ToByte(IP_Array[0]); //连接目的地址(服务器)
request[nIndex++] = Convert.ToByte(IP_Array[1]);
request[nIndex++] = Convert.ToByte(IP_Array[2]);
request[nIndex++] = Convert.ToByte(IP_Array[3]);
//byte转化为int

//服务器端口dest_port
int port = Convert.ToInt32(dest_port);
string hexOutput = String.Format("{0:X}", port);
//Console.WriteLine("Hexadecimal value of {0} is {1}", port, hexOutput);
request[nIndex++] = (byte)(dest_port / 256);
request[nIndex++] = (byte)(dest_port % 256);
s.Send(request, nIndex, SocketFlags.None);

a = s.Receive(sreceive, sreceive.Length, SocketFlags.None);
Console.WriteLine("返回消息以下:");
Console.WriteLine("a =" + a); //返回信息的长度
Console.WriteLine("VER =" + sreceive[0]);
Console.WriteLine("REP =" + sreceive[1]);
Console.WriteLine("RSV =" + sreceive[2]);
Console.WriteLine("ATYP=" + sreceive[3]);
Console.WriteLine("返回信息IP=" + sreceive[4]);
Console.WriteLine("返回信息IP=" + sreceive[5]);
Console.WriteLine("返回信息IP=" + sreceive[6]);
Console.WriteLine("返回信息IP=" + sreceive[7]);
Console.WriteLine("端口信息1=" + sreceive[8]);
Console.WriteLine("端口信息2=" + sreceive[9]);
Console.WriteLine("");
if (sreceive[1]==0)
{
try
{
//发送让代理服务器转发的消息
string message = "{'head':'login','name':'2535','mm':'123'}";
s.Send(Encoding.Default.GetBytes(message));
//接收代理服务器返回的消息
while ((a = s.Receive(result)) > 0)
{
sb.Append(Encoding.Default.GetString(result, 0, a));
}
}
catch
{
//通信过程出问题,异常关闭socket
s.Close();
}
Result = sb.ToString();
Console.WriteLine("Result="+ Result);
//信息收发完关闭与代理服务器连接
s.Close();
Console.WriteLine("代理服务结束");
}

}
}
}
}
}


目的IP(destAddress )和端口 是我后台服务器所在的IP和端口,向后台发送消息后收到的消息无论如何都不该是空,因为后台是会判断消息后返回不会空的消息,但是实际运行后的结果是这样:

Result最后的返回结果应该就是代理服务器访问了destAddress 以后返回回来的信息吧,但是最后结果是空,希望大神能够给个建议,研究了很久没发现是哪里的问题,小弟在此谢过。
...全文
392 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
lsgzs2018 2019-10-12
  • 打赏
  • 举报
回复
使用驱动拦截网络数据,然后R3用SOCKS5转发到你的代理服务器。
可以达到每个进程不同IP的效果,上个图吧。

4,358

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧