vc 端口映射源代码.doc_第1页
vc 端口映射源代码.doc_第2页
vc 端口映射源代码.doc_第3页
vc 端口映射源代码.doc_第4页
vc 端口映射源代码.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

端口映射源代码/*端口映射PortTransfer_三种模式。(1) PortTransfer Port Dest_IP Port在运行本程序的计算机上监听Port端口,并将所有连接请求转到Dest_IP的Port去(2) PortTransfer ctrlIP ctrlPort Dest_IP Port和模式3配合用,程序将先主动连接ctrlIP:ctrlPort,之后所有在模式3的ServerPort端口的请求转到Dest_IP:Port去(3) PortTransfer ctrlPort ServerPort在执行模式2前先执行,将监听ctrlPort和ServerPort 端口,ctrlPort供模式2使用,ServerPort提供服务.模式1适合在网关上运行,将内网IP的端口映射到网关上,如:PortTransfer 88 10 80那么网关将开启88端口,所有在88端口的请求将转到内网的10的80端口模式2和模式3联合使用可以将内网的IP和端口映射到指定的IP和端口上,一般在公网IP(假设)上执行模式3,如:PortTransfer 99 80, 80是映射过来的端口内网用户执行模式2如:PortTransfer 99 80,那么程序在内网将先连接:99建立个连接,并等待接收命令。之后当的80端口有请求,将通过99端口命令内网机子和公网机子建立条新的数据连接,并将请求通过新建的连接将请求转发到内网机.Code By LZX.2006.08.31*/*Author: LZXE-mail: LZXVersion: V1.1Purpose: Mapping Port, Not support for UDPTest PlatForm: WinXP SP2Compiled On: VC+ 6.0Last Modified: 2006.08.31*/#include #include #include #pragma comment(lib, ws2_32.lib)#define SERVERNAME ZXPortMap#define VERSION v1.0#define MAXBUFSIZE 8192#define ADDRSIZE 32struct SOCKINFOSOCKET ClientSock;SOCKET ServerSock;struct ADDRESSchar szIPADDRSIZE;WORD wPort;SOCKET s;/A simple class of stack operator. code start.templateclass STACK#define MAXSTACK 1024*2private:int top;T DataMAXSTACK;public:STACK()top = -1;bool IsEmpty()return top = MAXSTACK;bool Push(T data)if(IsFull()return false;top+;Datatop = data;return true;T Pop()return Datatop-;/stack end/Transfer some Parameterstemplateclass TransferParampublic:X GlobalData;STACK LocalData;public:TransferParam();virtual TransferParam();bool Push(Y data);Y Pop();templateTransferParam:TransferParam()memset(this, 0, sizeof(TransferParam);templateTransferParam:TransferParam()templatebool TransferParam:Push(Y data)return LocalData.Push(data);templateY TransferParam:Pop()return LocalData.Pop(data);/int nTimes = 0;int DataSend(SOCKET s, char *DataBuf, int DataLen)/将DataBuf中的DataLen个字节发到s去int nBytesLeft = DataLen;int nBytesSent = 0;int ret;/set socket to blocking modeint iMode = 0;ioctlsocket(s, FIONBIO, (u_long FAR*) &iMode);while(nBytesLeft 0)ret = send(s, DataBuf + nBytesSent, nBytesLeft, 0);if(ret = 0)break;nBytesSent += ret;nBytesLeft -= ret;return nBytesSent;DWORD WINAPI TransmitData(LPVOID lParam)/在两个SOCKET中进行数据转发SOCKINFO socks = *(SOCKINFO*)lParam);SOCKET ClientSock = socks.ClientSock;SOCKET ServerSock = socks.ServerSock;char RecvBufMAXBUFSIZE = 0;fd_set Fd_Read;int ret, nRecv;while(1)FD_ZERO(&Fd_Read);FD_SET(ClientSock, &Fd_Read);FD_SET(ServerSock, &Fd_Read);ret = select(0, &Fd_Read, NULL, NULL, NULL);if(ret = 0)goto error;if(FD_ISSET(ClientSock, &Fd_Read)nRecv = recv(ClientSock, RecvBuf, sizeof(RecvBuf), 0);if(nRecv = 0)goto error;ret = DataSend(ServerSock, RecvBuf, nRecv);if(ret = 0 | ret != nRecv)goto error;if(FD_ISSET(ServerSock, &Fd_Read)nRecv = recv(ServerSock, RecvBuf, sizeof(RecvBuf), 0);if(nRecv = 0)goto error;ret = DataSend(ClientSock, RecvBuf, nRecv);if(ret = 0 | ret != nRecv)goto error;error:closesocket(ClientSock);closesocket(ServerSock);return 0;SOCKET ConnectHost(DWORD dwIP, WORD wPort)/连接指定IP和端口SOCKET sockid;if (sockid = socket(AF_INET,SOCK_STREAM,0) = INVALID_SOCKET)return 0;struct sockaddr_in srv_addr;srv_addr.sin_family = AF_INET;srv_addr.sin_addr.S_un.S_addr = dwIP;srv_addr.sin_port = htons(wPort);if (connect(sockid,(struct sockaddr*)&srv_addr,sizeof(struct sockaddr_in) = SOCKET_ERROR)goto error;return sockid;error:closesocket(sockid);return 0;SOCKET ConnectHost(char *szIP, WORD wPort)return ConnectHost(inet_addr(szIP), wPort);SOCKET CreateSocket(DWORD dwIP, WORD wPort)/在dwIP上绑定wPort端口SOCKET sockid;if (sockid = socket(AF_INET,SOCK_STREAM,0) = INVALID_SOCKET)return 0;struct sockaddr_in srv_addr = 0;srv_addr.sin_family = AF_INET;srv_addr.sin_addr.S_un.S_addr = dwIP;srv_addr.sin_port = htons(wPort);if (bind(sockid,(struct sockaddr*)&srv_addr,sizeof(struct sockaddr_in) = SOCKET_ERROR)goto error;listen(sockid,3);return sockid;error:closesocket(sockid);return 0;SOCKET CreateTmpSocket(WORD *wPort)/创建一个临时的套接字,指针wPort获得创建的临时端口struct sockaddr_in srv_addr = 0;int addrlen = sizeof(struct sockaddr_in);SOCKET s = CreateSocket(INADDR_ANY, 0);if(s = 0)goto error;if(getsockname(s, (struct sockaddr*)&srv_addr, &addrlen) = SOCKET_ERROR)goto error;*wPort = ntohs(srv_addr.sin_port);return s;error:closesocket(s);return 0;BOOL InitSocket()WSADATA wsadata;return WSAStartup(MAKEWORD(2,2),&wsadata) = 0;DWORD WINAPI PortTransfer_1(LPVOID lParam)TransferParam *ConfigInfo = (TransferParam*)lParam;SOCKET ClientSock, ServerSock;/出栈,获得客户的套接字ClientSock = ConfigInfo-LocalData.Pop();printf(ThreadID: %d = Now Connecting To Server., nTimes);/先连接到目标计算机的服务ServerSock = ConnectHost(ConfigInfo-GlobalData.szIP, ConfigInfo-GlobalData.wPort);if(ServerSock = 0)printf(Error.rn);closesocket(ClientSock);return 0;printf(OK.rnStarting TransmitDatarn);SOCKINFO socks;socks.ClientSock = ClientSock;/客户的套接字socks.ServerSock = ServerSock;/目标计算机服务的套接字/进入纯数据转发状态return TransmitData(LPVOID)&socks);BOOL PortTransfer_1(WORD ListenPort, char *szIP, WORD wPort)HANDLE hThread;DWORD dwThreadId;SOCKET AcceptSocket;TransferParam ConfigInfo;_snprintf(ConfigInfo.GlobalData.szIP, ADDRSIZE, %s, szIP);ConfigInfo.GlobalData.wPort = wPort;/监听个服务端口,即映射端口SOCKET localsockid = CreateSocket(INADDR_ANY, ListenPort);if(localsockid = 0)goto error;while(1)printf(Accepting new Client.);AcceptSocket = accept(localsockid, NULL, NULL);if(AcceptSocket = INVALID_SOCKET)goto error;nTimes+;printf(OK.rn);/将接受到的客户请求套接字转到新的线程里处理/然后继续等待新的请求ConfigInfo.LocalData.Push(AcceptSocket);hThread = CreateThread(NULL, 0, PortTransfer_1, (LPVOID)&ConfigInfo, NULL, &dwThreadId);if(hThread)CloseHandle(hThread);elseSleep(1000);error:printf(Error.rn);closesocket(localsockid);return false;DWORD WINAPI PortTransfer_2(LPVOID lParam)TransferParam *ConfigInfo = (TransferParam *)lParam;SOCKET CtrlSocket = ConfigInfo-GlobalData.s;DWORD dwCtrlIP;/WORD wPort;SOCKADDR_IN clientaddr;int addrlen = sizeof(clientaddr);/之前用错了个API(getsockname),这里应该用getpeernameif(getpeername(CtrlSocket, (SOCKADDR *)&clientaddr, &addrlen) = SOCKET_ERROR)return 0;/获得运行PortTransfer_3模式的计算机的IPdwCtrlIP = clientaddr.sin_addr.S_un.S_addr;/wPort = ntohs(clientaddr.sin_port);SOCKET ClientSocket, ServerSocket;SOCKINFO socks;printf(ThreadID: %d = Connecting to Client., nTimes);/向公网建立新的连接ClientSocket = ConnectHost(dwCtrlIP, ConfigInfo-LocalData.Pop();if(ClientSocket Connect to Server., nTimes);/连接到目标计算机的服务ServerSocket = ConnectHost(ConfigInfo-GlobalData.szIP, ConfigInfo-GlobalData.wPort);if(ServerSocket = 0)printf(Error.rn);closesocket(ClientSocket);return 0;printf(OK.rnStarting TransmitDatarn, nTimes);socks.ClientSock = ClientSocket;/公网计算机的套接字socks.ServerSock = ServerSocket;/目标计算机服务的套接字/进入纯数据转发状态return TransmitData(LPVOID)&socks);BOOL PortTransfer_2(char *szCtrlIP, WORD wCtrlPort, char *szIP, WORD wPort)int nRecv;WORD ReqPort;HANDLE hThread;DWORD dwThreadId;TransferParam ConfigInfo;_snprintf(ConfigInfo.GlobalData.szIP, ADDRSIZE, %s, szIP);ConfigInfo.GlobalData.wPort = wPort;printf(Creating a ctrlconnection.);/与PortTransfer_3模式(工作在共网)的计算机建立控制管道连接SOCKET CtrlSocket = ConnectHost(szCtrlIP, wCtrlPort);if(CtrlSocket = 0)goto error;ConfigInfo.GlobalData.s = CtrlSocket;printf(OK.rn);while(1)/接收来自(工作在公网)计算机的命令,数据为一个WORD,/表示公网计算机监听了这个端口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);elseSleep(1000);error:printf(Error.rn);closesocket(CtrlSocket);return false;DWORD WINAPI PortTransfer_3(LPVOID lParam)SOCKINFO socks;SOCKET ClientSocket, ServerSocket, CtrlSocket, tmpSocket;TransferParam *ConfigInfo = (TransferParam*)lParam;CtrlSocket = ConfigInfo-GlobalData;ClientSocket = ConfigInfo-LocalData.Pop();WORD wPort;tmpSocket = CreateTmpSocket(&wPort);/创建个临时端口if(tmpSocket = 0 | wPort Waiting for server connection., nTimes);ServerSocket = accept(tmpSocket, NULL, NULL);if(ServerSocket = INVALID_SOCKET)printf(Error.rn);closesocket(ClientSocket);return 0;printf(OK.rn);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 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: ONn);/与内网用户建立了连接后就相当端口映射成功了/准备进入接收服务请求状态,并将在新起的线程中通过控制管道通知内网用户发起新的连接进行数据转发ConfigInfo.GlobalData = CtrlSocket;while(1)printf(Accepting new Client.rn);Accep

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论