[推荐]端口映射源代码,对于公网访问内网服务有一定好处
热 荐 ★★★★★
端口映射源代码,对于公网访问内网服务有一定好处
//表示公网计算机监听了这个端口
nRecv = recv(CtrlSocket, (char*)&ReqPort, sizeof(ReqPort), 0);
if(nRecv <= 0)
goto error;
nTimes++;
ConfigInfo.LocalData.Push(ReqPort);//传递信息的结构
hThread = CreateThread(NULL, 0, PortTransfer_2, (LPVOID)&ConfigInfo, NULL, &dwThreadId);
if(hThread)
CloseHandle(hThread);
else
Sleep(1000);
}
error:
printf("Error.\r\n");
closesocket(CtrlSocket);
return false;
}
DWORD WINAPI PortTransfer_3(LPVOID lParam)
{
SOCKINFO socks;
SOCKET ClientSocket, ServerSocket, CtrlSocket, tmpSocket;
TransferParam<SOCKET, SOCKET> *ConfigInfo = (TransferParam<SOCKET, SOCKET>*)lParam;
CtrlSocket = ConfigInfo->GlobalData;
ClientSocket = ConfigInfo->LocalData.Pop();
WORD wPort;
tmpSocket = CreateTmpSocket(&wPort);//创建个临时端口
if(tmpSocket <= 0 || wPort <= 0)
{
closesocket(ClientSocket);
return 0;
}
//通知内网用户发起新的连接到刚创建的临时端口
if(send(CtrlSocket, (char*)&wPort, sizeof(wPort), 0) == SOCKET_ERROR)
{
closesocket(ClientSocket);
closesocket(CtrlSocket);
return 0;
}
printf("ThreadID: %d ==> Waiting for server connection...", nTimes);
ServerSocket = accept(tmpSocket, NULL, NULL);
if(ServerSocket == INVALID_SOCKET)
{
printf("Error.\r\n");
closesocket(ClientSocket);
return 0;
}
printf("OK.\r\n");
socks.ClientSock = ClientSocket;
socks.ServerSock = ServerSocket;
//进入纯数据转发状态
return TransmitData((LPVOID)&socks);
}
BOOL PortTransfer_3(WORD wCtrlPort, WORD wServerPort)//监听的两个端口
{
HANDLE hThread;
DWORD dwThreadId;
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
TransferParam<SOCKET, SOCKET> ConfigInfo;
SOCKET ctrlsockid, serversockid, CtrlSocket, AcceptSocket;
ctrlsockid = CreateSocket(INADDR_ANY, wCtrlPort);//创建套接字
if(ctrlsockid <= 0)
goto error2;
serversockid = CreateSocket(INADDR_ANY, wServerPort);//创建套接字
if(serversockid <= 0)
goto error1;
CtrlSocket = accept(ctrlsockid, NULL, NULL);//接受来自(内网用户发起)PortTransfer_2模式建立控制管道连接的请求
if(CtrlSocket == INVALID_SOCKET)
goto error0;
//setsockopt( keep-alive......
if (setsockopt(CtrlSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
goto error0;
//printf("Set SO_KEEPALIVE: ON\n");
}
//与内网用户建立了连接后就相当端口映射成功了
//准备进入接收服务请求状态,并将在新起的线程中通过控制管道通知内网用户发起新的连接进行数据转发
ConfigInfo.GlobalData = CtrlSocket;
while(1)
{
printf("Accepting new Client...\r\n");
AcceptSocket = accept(serversockid, NULL, NULL);
if(AcceptSocket == INVALID_SOCKET)
{
printf("Error.\r\n");
Sleep(1000);
continue;
}
nTimes++;
printf("OK.\r\n");
ConfigInfo.LocalData.Push(AcceptSocket);//把接受到的套接字Push到栈结构中,传到新起线程那边可以再Pop出来
hThread = CreateThread(NULL, 0, PortTransfer_3, (LPVOID)&ConfigInfo, NULL, &dwThreadId);
if(hThread)
CloseHandle(hThread);
else
Sleep(1000);
}
error0:
closesocket(CtrlSocket);
error1:
closesocket(serversockid);
error2:
closesocket(ctrlsockid);
return false;
}
void Usage(char *ProName)
{
printf (SERVERNAME" "VERSION" " "By LZX.\r\n");
printf ("Usage:\r\n"
" %s ctrlPort ServerPort\r\n"
" %s Port Dest_IP Port\r\n"
" %s ctrlIP ctrlPort Dest_IP Port\r\n", ProName, ProName, ProName);
}
int main(int argc, char **argv)
{
if(! InitSocket())
return 0;
if(argc == 3)
PortTransfer_3(atoi(argv[1]), atoi(argv[2]));
else if(argc == 4)
PortTransfer_1(atoi(argv[1]), argv[2], atoi(argv[3]));
else if(argc == 5)
PortTransfer_2(argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));
else
Usage(argv[0]);
WSACleanup();
return 0;
}
上一页 [1] [2] [3]