热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用socks5将游戏的服务器连接通过本地SS服务器代理连接到加速服务器,实现游戏加速。

水平有限,简单记录下实现过程:首先准备一个开源项目SSCAPhttps:sourceforge.netpsscapcodecimastertree(c

水平有限,简单记录下实现过程:

首先准备一个开源项目SSCAP https://sourceforge.net/p/sscap/code/ci/master/tree/ (c++ mfc sscap源码)。

SSCap是一个本地代理服务器,SSCap是一个Windows下C++版的Shadowsocks客户端. 相比其它的客户端更稳定更快速,不会出现其它版本中常现的接收数据错误。

通过SSCap可以启动本地代理服务器。你可以让IE或其他需要软件通过SOCKS5访问的软件先连接到 SSCAP,SSCAP再将请求加密后再连接到服务器。服务器可以将请求转发到国外游戏服务器,实现网络游戏加速。

SSCAP界面:

SSCap是开源的。本文将SScap的功能整合起来。实现对魔兽世界怀旧服LH网络加速的功能。

原理很简单:

1、先整合sscap的功能,将本地服务器启动起来。

// 加载ss服务器列表CSSConfigInfo *pCfg = GetConfigInfo();CSSNodeInfo* pNode = new CSSNodeInfo(0);pNode->id = 0;pNode->server = "140.0.0.00";pNode->server_port = 65501;pNode->password = "1234"; pNode->method = "aes-256-cfb";pNode->enable = true;pNode->Upload_traffic = 7450.00;pNode->Download_traffic = 21477.00;pNode->ConnectedTimes = 12;pNode->lastStatus = -1;pCfg->ssNodeInfo.clear();pCfg->ssNodeInfo.push_back(pNode);pCfg->localSocksUser = "local_user";pCfg->localSocksPass = "local_pass";pCfg->localPort = 1080;pCfg->isPrivoxyRunned = RunPrivoxy( );RestartLocalSocketService(FALSE);

那么本地服务器就启动好了。127.0.0.1:1080  登陆账号:local_user    登陆密码:local_pass

2、启动魔兽世界6.0。注入DLL,拦截ws2_32.dll的connect方法。

DetourRestoreAfterWith();//恢复原来的状态DetourTransactionBegin();//拦截开始DetourUpdateThread(GetCurrentThread());//刷新当前线程 //以下为hook connect内容g_trueConnect = (_gconnect)DetourFindFunction("Ws2_32.dll", "connect");g_trueWSAConnect = (_gWSAConnect)DetourFindFunction("Ws2_32.dll", "WSAConnect");DetourAttach(&(PVOID&)g_trueConnect,hook_connect);DetourAttach(&(PVOID&)g_trueWSAConnect,hook_WSAConnect);if( DetourTransactionCommit() == NO_ERROR )//拦截生效{WriteLog(_T("hook success"));}elseWriteLog(_T("hook faild"));

int _stdcall hook_connect(SOCKET s, struct sockaddr *name, int namelen)
{CString strDbgInfo;strDbgInfo.Format(_T("Socket in hook connect:%d"),s);//修改目的IP为VIPSOCKADDR_IN* addr =(SOCKADDR_IN*)name;//如果IP是指定要修改端口的IP,就改掉端口char * ipaddr=NULL;ipaddr = inet_ntoa(addr->sin_addr);//原游戏连接信息TCHAR temp[255];memset(temp,0,255); char* proxyserver = "127.0.0.1";int proxyport = 1081;char* proxyuser = "local_user";char* proxypwd = "local_pass";int iRet = ConnecToProxyServer(s,proxyserver,proxyport,proxyuser,proxypwd,3,ipaddr,ntohs(addr->sin_port));if (iRet>=0){WriteLog(_T("in connecta: connect socks5 success 1!"));}else{memset(temp,0,255);wsprintf(temp,_T("Err connect ss5:%d"),iRet);WriteLog(temp);}return iRet;
}

//代理服务器登录
//char* g_proxyserver = "140.1xx.1x.1xx";
//int g_proxyport = 65500;
//char* g_proxyuser = "";
//char* g_proxypwd = "";
//int g_proxyid = 3; //2 - sock4代理 3 - sock5代理
//char server_name[100]= {0}; //真正的服务器地址
//int server_port=8000; //真正的服务器端口
int ConnecToProxyServer(SOCKET m_hSocketpop,char* g_proxyserver,int g_proxyport,char* g_proxyuser,char* g_proxypwd,int g_proxyid,char* server_name,int server_port,int connectType)
{//原游戏连接信息SOCKADDR_IN ToAddr;memset(&ToAddr, 0, sizeof(ToAddr));ToAddr.sin_family &#61; AF_INET; ToAddr.sin_addr.s_addr &#61; inet_addr(g_proxyserver);//这是我的SOCKS服务器ToAddr.sin_port &#61; htons(g_proxyport); int retCt &#61; -1;if (connectType &#61;&#61; 1)retCt &#61; g_trueWSAConnect(m_hSocketpop,(SOCKADDR*)&ToAddr,sizeof(ToAddr),NULL,NULL,NULL ,NULL);elseretCt &#61; g_trueConnect(m_hSocketpop,(SOCKADDR*)&ToAddr,sizeof(ToAddr));if( SOCKET_ERROR &#61;&#61; retCt ){int iErr &#61; WSAGetLastError(); if (iErr&#61;&#61;WSAEWOULDBLOCK){fd_set fdWrite;timeval tv;FD_ZERO(&fdWrite);//初始化fd_setFD_SET(m_hSocketpop,&fdWrite);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;int nRet &#61; select(0,NULL,&fdWrite,NULL,&tv);if (nRet<&#61;0){closesocket(m_hSocketpop);return -111;}}else{closesocket(m_hSocketpop);return -112;}}char buf[100] &#61; {0};if(g_proxyid &#61;&#61; 3) //sock5 代理方式{// 让PROXY选择认证方法buf[0] &#61; 0x05;buf[1] &#61; 0x02; //确认2种认证方式 无需认证和需要认证buf[2] &#61; 0x00; // 无需认证buf[3] &#61; 0x02; // 需要认证WriteLog(_T("Send a request asking if authentication is required"));if(send(m_hSocketpop,(const far char*)buf,4,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -12;}//查询是否有返回fd_set fdread;timeval tv;FD_ZERO(&fdread);//初始化fd_setFD_SET(m_hSocketpop,&fdread);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;int nRet;nRet &#61; select(0,&fdread,NULL,NULL,&tv);if (nRet<&#61;0){return -122;}//接收返回if(recv(m_hSocketpop,buf,10,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -13;}if(buf[1] &#61;&#61; 0x02){//需要认证WriteLog(_T("need auth"));char userStr[128] &#61; {0};userStr[0]&#61;0x01;userStr[1]&#61;strlen(g_proxyuser);strcpy(userStr&#43;2,g_proxyuser);userStr[2&#43; strlen(g_proxyuser)]&#61; strlen(g_proxypwd);strcpy(userStr&#43;3&#43; strlen(g_proxyuser),g_proxypwd);int result&#61;send(m_hSocketpop,userStr,strlen(userStr), 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}Sleep(100);char validateChar[2] &#61; {1};result&#61;recv(m_hSocketpop,validateChar,2, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}if(validateChar[1]!&#61;&#39;\x00&#39;){//认证失败closesocket(m_hSocketpop);return -1;}}// 向PROXY服务器发送CONNECT 请求&#xff0c;WriteLog(_T("Send connect request to PROXY server!"));memset(buf, 0, 100);buf[0] &#61; 0x05;buf[1] &#61; 0x01; // connection request.buf[2] &#61; 0x00; // reserved!buf[3] &#61; 0x01; // address type:Ip V4 ;*((ULONG*)(buf&#43;4))&#61;inet_addr(server_name);*((USHORT*)(buf&#43;8))&#61;htons(server_port);if(send(m_hSocketpop,(const far char*)buf,10,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -14;}//Sleep(100); FD_ZERO(&fdread);//初始化fd_setFD_SET(m_hSocketpop,&fdread);tv.tv_sec &#61; 30;tv.tv_usec &#61; 0;nRet &#61; select(0,&fdread,NULL,NULL,&tv);if (nRet<&#61;0){return -141;}// 接收PROXY服务器返回的REPLYmemset(buf, 1, 100);if(recv(m_hSocketpop,buf, 20,0) &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -15;}if(buf[1] !&#61; 0) // 只有当第二个字节为0时&#xff0c;才表示成功。{// printf("Cannot connect to the remote server!\n");closesocket(m_hSocketpop);return -16;}// theApp.m_ClientSocket.Attach(m_hSocketpop);}if(g_proxyid &#61;&#61; 2) //sock4 代理方式{int result;memset(buf, 0, 100);buf[0] &#61; 0x04;buf[1] &#61; 0x01; // connection request.*((USHORT*)(buf&#43;2))&#61;htons(server_port);*((ULONG*)(buf&#43;4))&#61;inet_addr(server_name);buf[8] &#61; 0x00;result &#61; send(m_hSocketpop, (const far char*)buf, 9, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}Sleep(100);char EchoStr[10];memset(EchoStr,0,10);result&#61;recv(m_hSocketpop,EchoStr,8, 0);if(result &#61;&#61; SOCKET_ERROR){closesocket(m_hSocketpop);return -1;}if(EchoStr[1] !&#61; 90){closesocket(m_hSocketpop);return -1;}// theApp.m_ClientSocket.Attach(m_hSocketpop);}return 0;
}

游戏会建立与本地服务器的连接&#xff0c;本地服务器会将游戏请求通过sock5发送到服务器上。实现游戏加速。

服务端架设参考&#xff1a;

用shadowsocks-libev架设服务器端&#xff1a;

https://blog.csdn.net/wwzuizz/article/details/78194159


推荐阅读
  • 在 CentOS 6.5 系统上部署 VNC 服务器的详细步骤与配置指南
    在 CentOS 6.5 系统上部署 VNC 服务器时,首先需要确认 VNC 服务是否已安装。通常情况下,VNC 服务默认未安装。可以通过运行特定的查询命令来检查其安装状态。如果查询结果为空,则表明 VNC 服务尚未安装,需进行手动安装。此外,建议在安装前确保系统的软件包管理器已更新至最新版本,以避免兼容性问题。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • Git命令基础应用指南
    本指南详细介绍了Git命令的基础应用,包括如何使用`git clone`从远程服务器克隆仓库(例如:`git clone [url/path/repository]`)以及如何克隆本地仓库(例如:`git clone [local/path/repository]`)。此外,还提供了常见的Git操作技巧,帮助开发者高效管理代码版本。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 通过使用七牛云存储服务,本文详细介绍了如何将本地图片高效上传至云端,并实现了内容的便捷管理。借助七牛云的 Python SDK,文章提供了从认证到文件上传的具体代码示例,包括导入必要的库、生成上传凭证以及处理文件路径等关键步骤。此外,还探讨了如何利用七牛云的 URL 安全编码功能,确保数据传输的安全性和可靠性。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 本文深入解析了JDK 8中HashMap的源代码,重点探讨了put方法的工作机制及其内部参数的设定原理。HashMap允许键和值为null,但键为null的情况只能出现一次,因为null键在内部通过索引0进行存储。文章详细分析了capacity(容量)、size(大小)、loadFactor(加载因子)以及红黑树转换阈值的设定原则,帮助读者更好地理解HashMap的高效实现和性能优化策略。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 在Ubuntu上安装MySQL时解决缺少libaio.so.1错误及libaio在MySQL中的重要性分析
    在Ubuntu系统上安装MySQL时,遇到了缺少libaio.so.1的错误。本文详细介绍了如何解决这一问题,并深入探讨了libaio库在MySQL性能优化中的重要作用。对于初学者而言,理解这些依赖关系和配置步骤是成功安装和运行MySQL的关键。通过本文的指导,读者可以顺利解决相关问题,并更好地掌握MySQL在Linux环境下的部署与管理。 ... [详细]
  • JavaScript XML操作实用工具类:XmlUtilsJS技巧与应用 ... [详细]
  • 寒假作业解析:第三周 2月12日 第7题
    尽快完成之前的练习任务!每日一练2.1 Problem A Laurenty and Shop 的题目要求是选择两条不同的路线以最小化总的等待时间。简要分析:通过对比不同路线的等待时间,可以找到最优解。此问题可以通过动态规划或贪心算法来解决,具体取决于路线的复杂性和约束条件。 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
author-avatar
张群羽圣文
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有