锁定老帖子 主题:TCP to TCP 数据转发技术
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-21
我们部门在内网有一台Web服务器A,用于部门文档信息管理,可分公司的员工,或出差的员工,都不能直接访问这台机器。 所以还得把发邮件来完成文档的提交。如何实现外地员工能访问Web服务器A呢?公司有一台可以访问外网的机器B,要是在B上运行 一个数据转发程序,固定地把外网发送到某个端口的数据转发到A上的Web端口,同时把A上回送的数据转发出去,不就一切OK了吗! 设计 //主程序 Main() { beginthread(Main Thread()); } //主线程 Main Thread(Param) { 创建"本地监听SOCK" while(true) { 等待客户端连接 等到后,创建"目标SOCK" 连接到目的地 连接成功后,创建"Wait Thread" } } //Wait 线程 Wait Thread(Param) { 创建"连接SOCK"->"目标SOCK"数据转发Thread 创建"目标SOCK"->"连接SOCK"数据转发Thread 等待这两个线程结束 释放SOCK资源 } //TCP2TCP数据转发线程 TCP2TCP Thread(Param) { SOCK FROM,TO while(read >0) { read(From,Buff); Send(To,Buff); } } 参考代码 参数结构 struct AGENTGATEWAYINFO{ int LocalPort; //本地Port int TargetPort; //目标Port int TargetPort1; //目标Port2 char TargetIP[64]; //目标IP char SpecialIP[64]; //特定的IP int SpecialTargetPort;//特定的目标port char SpecialTargetIP[64];//特定的目标IP int ProxyType; //代理类型 char ProxyIP[30]; //代理IP int ProxyPort; //代理端口 char ProxyUser[50]; //代理用户 char ProxyPassword[50];//代理密码 }; //主线程 DWORD mainthread(LPVOID lpvoid) { //获取传人的参数 AGENTGATEWAYINFO *psi = (AGENTGATEWAYINFO *)lpvoid; AGENTGATEWAYINFO si; memcpy(&si,psi,sizeof(AGENTGATEWAYINFO)); SOCKET listensock,sock[2]; unsigned long hostip; char chostip[64]="0"; delete psi; printf("\n************Start Agent Tcp GateWay %d==>%s:%d****************",si.LocalPort,si.TargetIP,si.TargetPort); psi = NULL; hostip=inet_addr(chostip); //先建立本地监听socket,用来等待需要转发的连接 if((listensock = socket(AF_INET,SOCK_STREAM,0)) == NULL) { printf("\nTcpGateWay:Can't create incoming socket.\n"); return -1; } sockaddr_in incomingsin; incomingsin.sin_family = AF_INET; incomingsin.sin_port = htons(si.LocalPort); if(hostip!=INADDR_NONE) { incomingsin.sin_addr.s_addr=hostip; } else { printf("\nTcpGateWay:Can't look up local ip.\n"); return -1; } sockaddr_in clientaddr; int iclientaddr = sizeof(clientaddr); bind(listensock,(LPSOCKADDR)&incomingsin,sizeof(sockaddr)); listen(listensock,10); printf("\nTcpGateWay:Listening at ip: %s , port: %d.\n",inet_ntoa(incomingsin.sin_addr) , si.LocalPort); _AddSock(listensock); while (1) { //开始等待新的连接 memset( &clientaddr, 0 , sizeof( clientaddr) ); sock[0] = accept(listensock,(struct sockaddr *)&clientaddr,&iclientaddr); if(sock[0] == -1) { printf("client eq -1 ,break it!\n"); Sleep(1000); continue; } else { //等到了 SOCKETINFO *psgc = new SOCKETINFO(); psgc->sock[0] = sock[0]; strcpy(psgc->SockIP[0],inet_ntoa(clientaddr.sin_addr)); psgc->SockPort[0] = ntohs(clientaddr.sin_port); printf("\nTcpGateWay:Incoming connection from %s:%d.",psgc->SockIP[0],psgc->SockPort[0]); strcpy(psgc->SockIP[1],si.TargetIP); psgc->SockPort[1] = si.TargetPort; //产生一个目标SOCK if((psgc->sock[1] = socket(AF_INET,SOCK_STREAM,0)) == NULL) { printf("\nTcpGateWay:Can't create sending socket."); delete psgc; continue; } CWSocket wsock0 ; &nbp; wsock0.Attach(psgc->sock[1]); try { //通过代理连接目标 switch(si.ProxyType) { case 1://SOCK4 wsock0.ConnectViaSocks4(psgc->SockIP[1], psgc->SockPort[1],si.ProxyIP, si.ProxyPort); break; case 2://SOCK5 if(strlen(si.ProxyUser) > 0) { wsock0.ConnectViaSocks5(psgc->SockIP[1], psgc->SockPort[1],si.ProxyIP, si.ProxyPort, si.ProxyUser, si.ProxyPassword); }else { wsock0.ConnectViaSocks5(psgc->SockIP[1], psgc->SockPort[1],si.ProxyIP, si.ProxyPort); } break; case 3://HTTP11 { CString sProxyResponse; if(strlen(si.ProxyUser) > 0) { wsock0.ConnectViaHTTPProxy(psgc->SockIP[1], psgc->SockPort[1],si.ProxyIP, si.ProxyPort, sProxyResponse, si.ProxyUser, si.ProxyPassword); }else { wsock0.ConnectViaHTTPProxy(psgc->SockIP[1], psgc->SockPort[1],si.ProxyIP, si.ProxyPort,sProxyResponse); } } break; default: wsock0.Connect(psgc->SockIP[1],psgc->SockPort[1]); break; } } catch(CWSocketException* pEx) { pEx->Delete(); wsock0.Detach(); _DelSock(psgc->sock[1]); _DelSock(psgc->sock[0]); printf("\nTcpGateWay:Can't forward to %s:%d.",si.TargetIP,si.TargetPort); delete psgc; continue; } wsock0.Detach(); printf("\n%s:%d ==> %s:%d.\n",psgc->SockIP[0],psgc->SockPort[0],psgc->SockIP[1],psgc->SockPort[1]); DWORD threadid; //连接成功,创建监护线程,用来监控socket psgc->hWaitThread = CreateThread(NULL,0,waitthread,(LPVOID)psgc,NULL,&threadid); _AddThread(psgc->hWaitThread); } } _DelSock(listensock); return 0; } //监护线程,用来监控socket DWORD waitthread(LPVOID lpvoid) { SOCKETINFO *psgc = (SOCKETINFO *)lpvoid; HANDLE hWaitThread = psgc->hWaitThread; _AddSock(psgc->sock[1]); _AddSock(psgc->sock[0]); //创建连接端->目的端数据转发线程 psgc->hThreads[0] = CreateThread(NULL,0,tcp2tcp,(LPVOID)psgc,NULL,&psgc->id[0]); _AddThread(psgc->hThreads[0]); //创建目的端->连接端数据转发线程 psgc->hThreads[1] = CreateThread(NULL,0,tcp2tcp,(LPVOID)psgc,NULL,&psgc->id[1]); _AddThread(psgc->hThreads[1]); //等待线程结束 DWORD waiter; waiter = WaitForMultipleObjects(MAX_SOCKS,psgc->hThreads,FALSE,INFINITE); if(waiter == WAIT_OBJECT_0) { _DelThread(psgc->hThreads[0]); _DelSock(psgc->sock[0]); Sleep(50); _DelSock(psgc->sock[1]); WaitForSingleObject(psgc->hThreads[1],2000); _DelThread(psgc->hThreads[1]); }else if(waiter == WAIT_OBJECT_0+1) { _DelThread(psgc->hThreads[1]); _DelSock(psgc->sock[1]); Sleep(50); _DelSock(psgc->sock[0]); WaitForSingleObject(psgc->hThreads[0],2000); _DelThread(psgc->hThreads[0]); }else { _DelSock(psgc->sock[1]); Sleep(50); _DelSock(psgc->sock[0]); _DelThread(psgc->hThreads[1]); _DelThread(psgc->hThreads[0]); } printf("\n%s:%d Socket closed.\n",psgc->SockIP[0],psgc->SockPort[0]); delete psgc; _PostDelThread(hWaitThread); ExitThread(0); return 0; } DWORD WINAPI tcp2tcp(LPVOID lpvoid) { SOCKETINFO *psgc = (SOCKETINFO *)lpvoid; DWORD threadid=GetCurrentThreadId(); SOCKET s[2]; HANDLE ReadEvent = NULL ; BOOL isFirstRead=TRUE; CString sHexDispData; BOOL bIsDisplay0 = TRUE; if(psgc->id[0] == threadid) { s[0] = psgc->sock[0]; s[1] = psgc->sock[1]; ReadEvent = psgc->ReadEvent[0]; }else { s[1] = psgc->sock[0]; s[0] = psgc->sock[1]; ReadEvent = psgc->ReadEvent[1]; bIsDisplay0 = FALSE; } printf("\n***New TCP2TCP Thread %d recv %d send %d.\n",threadid,s[0],s[1]); char incomingbuff[maxsize]; int read = 1; while(read >0) { read = recv(s[0],incomingbuff, maxsize,0); if(read <=0 ) break; printf("\nTCP2TCP Thread %d recv %d bytes.",threadid,read); int npos=0; while(npos < read) { int nsendcount = send(s[1],incomingbuff+npos,read-npos,0); if(nsendcount <= 0 ) return 0; printf("\nTCP2TCP Thread %d send %d bytes.",threadid,nsendcount); npos += nsendcount; } } printf("\nTCP2TCP Thread %d LastError %d",threadid,GetLastError()); return 0; } 需要完整源代码请留言或和作者联系。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-09-23
做个端口映射就行了,或者建个隧道,网上方案很多没必要自己写代码。
750986570 写道 目的
我们部门在内网有一台Web服务器A,用于部门文档信息管理,可分公司的员工,或出差的员工,都不能直接访问这台机器。 所以还得把发邮件来完成文档的提交。如何实现外地员工能访问Web服务器A呢?公司有一台可以访问外网的机器B,要是在B上运行 一个数据转发程序,固定地把外网发送到某个端口的数据转发到A上的Web端口,同时把A上回送的数据转发出去,不就一切OK了吗! 需要完整源代码请留言或和作者联系。 |
|
返回顶楼 | |
发表时间:2011-09-25
高手啊 多谢你的指点
|
|
返回顶楼 | |
发表时间:2011-10-08
VPN可以而且简单
或者你在b电脑做一个web,作为A电脑的反向代理即可,让他下载呗。 |
|
返回顶楼 | |
发表时间:2011-10-09
如果是linux服务器的话,直接用iptables设置下就可以搞定了.
|
|
返回顶楼 | |
发表时间:2011-10-09
用VPN,我们就是这样用的
|
|
返回顶楼 | |
发表时间:2011-10-12
我公司 也是用 VPN 建立虚拟网络
|
|
返回顶楼 | |
发表时间:2011-10-14
最后修改:2011-10-14
家里路由一直挂着pptp ovpn服务,翻(公司)墙、访问内网资源、远程开机等非常方便。。。还有和朋友远程打dota.......
|
|
返回顶楼 | |
发表时间:2011-10-15
最后修改:2011-10-15
牛人,给我一份代码,谢谢!
star4evar@gmail.com |
|
返回顶楼 | |
发表时间:2011-10-18
SSH Tunnel, the easiest way!
|
|
返回顶楼 | |