TCP to TCP 数据转发技术
目的
我们部门在内网有一台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;
}
需要完整源代码请留言或和作者联系。
我们部门在内网有一台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;
}
需要完整源代码请留言或和作者联系。
相关推荐
C#实现 TCP/UDP与串口之间相互转发通信,包含多个实例,有心跳过滤等。包含串口之间相互转发。UDP与串口之间转发,TCP与串口之间相互转发。注释比较少,包含各种情况模拟事例,可自行参考相关描述。工程内包含多个...
在TCP转发服务器中,这个过程会进一步扩展,不仅接收客户端的连接,还接收目标服务器的信息,以便将客户端的数据转发到正确的位置。 Qt库中的`QTcpServer`类提供了一种方便的方式来实现TCP服务器。这个类能够监听...
标题中的“免费COM-to-TCP”指的是一个工具或软件,它允许用户将串行通信(COM接口)的数据转换并通过TCP/IP网络进行传输。这个工具在IT行业中尤其对那些需要远程控制或监控通过串口设备(如打印机、扫描仪、GPS模块...
Tcp2Com.exe作为中间件,监听特定的TCP端口,当接收到TCP连接请求时,它会将数据转发到指定的串口,并将串口接收到的数据转发回TCP连接。这种桥接模式使得远程客户端可以通过TCP/IP协议与串口设备进行实时交互,...
串口转网(COM_to_net)的过程类似,只是方向相反,即串口设备发送的数据通过服务器转换为TCP数据,然后发送给远程的TCP客户端。 在实际应用中,TCP与串口的转换涉及到网络编程、串口编程以及数据打包和解包等技术...
- 数据转发的代码 ```csharp void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string indata = sp.ReadExisting(); // 将indata发送到TcpClient...
在IT领域,P2P(Peer-to-Peer)通信是一种网络架构,其中每个参与者既是服务的消费者也是服务的提供者,而TCP(Transmission Control Protocol)是互联网上最基础的传输层协议,负责可靠的数据传输。NAT(Network ...
在IT领域,P2P(Peer-to-Peer)通信是一种网络通信模式,其中每个参与者既是客户端也是服务器,直接与其他参与者交换数据,而不需要通过中央服务器。TCP(Transmission Control Protocol)作为传输层的主要协议,被...
这个例子展示了如何创建一个简单的TCP服务器,它将接收到的数据转发回客户端。 通过理解这些基本概念和实践,你可以利用ESP8266构建自己的TCP服务器,实现远程控制、数据传输等功能。在实际应用中,还可以结合MQTT...
在IT领域,P2P(Peer-to-Peer)通信是一种网络通信模式,其中每个参与者既是客户端也是服务器,直接与其他参与者交换数据,而不需要通过中央服务器。TCP(Transmission Control Protocol)作为传输层的主要协议,...
在IT领域,P2P(Peer-to-Peer)通信是一种网络通信模式,其中每个参与者既是客户端也是服务器,直接与其他参与者交换数据,而不需要通过中央服务器。TCP(Transmission Control Protocol)作为传输层协议,通常用于...
在网络游戏领域,数据转发系统、方法以及网络转发设备扮演着至关重要的角色,它们是保障游戏稳定运行、降低延迟、优化玩家体验的关键技术。本压缩包包含的“数据转发系统、方法以及网络转发设备.pdf”文件,很可能是...
然而,这种技术对P2P(Peer-to-Peer)通信和TCP连接造成了障碍,因为NAT会隐藏内部设备的IP地址和端口,使得外部网络无法直接与之通信。 TCP是互联网协议栈中最核心的部分之一,它为应用层提供了可靠的数据传输服务...
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,它通过三次握手建立连接,并通过确认、重传机制确保数据的正确传输。在QT中,我们可以利用QTcpServer类来实现TCP服务器,QTcpSocket类则用于表示客户端和...
随着互联网的快速发展和技术进步,P2P(Peer-to-Peer)通信已成为一种常见的网络应用形式。然而,NAT(Network Address Translation,网络地址转换)的存在给P2P通信带来了挑战。NAT设备通过将私有IP地址转换为公共...
描述中提到的"utility to create a tcp listen/listen or connect/connect"进一步确认了这个工具的用途,即创建TCP监听(listen)或者TCP连接(connect)。 在TCP/IP协议栈中,TCP(传输控制协议)是面向连接的协议...
然而,它的功能并不仅限于HTTP和HTTPS协议,通过扩展模块,Nginx也能处理TCP协议的数据转发。"nginx_tcp_proxy_module-master"就是这样一个模块,它使Nginx具备了TCP代理的能力,可以用于负载均衡、流量控制等多种...
在基于TCP的P2P(peer-to-peer,对等网络)聊天程序中,每个节点既是服务端也是客户端,可以互相发送和接收消息。这种设计使得网络中的每个参与者都能直接与其他参与者通信,降低了中心服务器的压力。 【MFC框架】 ...
TCP/IP(Transmission Control Protocol/Internet Protocol)是一种网络协议簇,由多个协议组成,用于在计算机网络之间进行数据传输。这些协议共同工作,确保信息在网络上高效、可靠地传输。本文将详细介绍TCP/IP簇...