这个程序是我06年写的了,重新把它整理到我这个blog中。
程序的作用是将所有发到本地监听端口的数据发送到指定远程地址指定端口
也就是一个tcp端口转发程序
这个程序中pm.cpp是主线程包括了main函数
而ResendTread.cpp是最核心的部分
用来处理一个转发任务
测试该程序,可以找两个点对点通信的程序进行通信其信息经过转发程序pm转发
望有经验的高手可以给建议。
***************************************************************************
/*--- pm.h ---*/
#include <winsock2.h>
#include <iostream>
#include <process.h>
#include "fun.h"//Declare all function
#include "ResendThread.h"//Declare the thread function use for resend
***************************************************************************
/*--- pm.cpp ---*/
#include "pm.h"//Declare all function
//The important global variable
EPARAM ExternalParameter;
SOCKET sPARAM;
int main(int argc, char* argv[])
{
//Check the parameters
if( (ExternalParameter = CheckParameter(argc,argv)).error == 1 )
{
//If the number of parameters are incorrect, get out!
return 0;
}
//Initialize the winsock use WSA()
if( WSA())
{
//When the WSA() failed to initialize the winsock, get out!
return 0;
}
//Create the listening socket
SOCKET sock_l = SOCKET_ERROR;
sock_l = socket(AF_INET, SOCK_STREAM, 0); //tcp listen socket
sockaddr_in addr_l;//Local address for listen
addr_l.sin_addr.s_addr = INADDR_ANY;
addr_l.sin_family = AF_INET;
addr_l.sin_port = htons(ExternalParameter.localport);
//Bind the sock_l to local address and set it to listening mode
if ( SOCKET_ERROR == bind(sock_l, (sockaddr *)&addr_l, sizeof(addr_l)) )
{
std::cout<<"Sock_l bind failed!"<<std::endl;
std::cout<<"The error code is: "<<GetLastError()<<std::endl;
return 0;
}
if ( SOCKET_ERROR == listen(sock_l, 1024) )
{
std::cout<<"Sock_l listen failed!"<<std::endl;
std::cout<<"The error code is: "<<GetLastError()<<std::endl;
return 0;
}
//Wait the connect request and accept the connect return a new socket
//finally start a thread and continue listen
while(true)
{
SOCKET sock_c = SOCKET_ERROR;
sock_c = socket(AF_INET, SOCK_STREAM, 0); //tcp listen socket
int len = sizeof(addr_l);
if (SOCKET_ERROR == (sock_c = accept(sock_l, (sockaddr *)&addr_l, &len)) )
{
std::cout<<"Accept a source failed!"<<std::endl;
std::cout<<"The error code is: "<<GetLastError()<<std::endl;
}
//Start a new thread
sPARAM = sock_c;
_beginthread(Resend,0,NULL);
}
return 0;
}
***************************************************************************
/*--- ResendThread.h ---*/
void Resend(LPVOID param);
***************************************************************************
/*--- fun.h ---*/
void Help();//when the user input the incorrect parameter show tutorial
struct EPARAM
{
int localport;
int remoteport;
unsigned long addr;
int error;
};
EPARAM CheckParameter(int argc, char* argv[]);//Check the external parameter
int WSA();//Initialize the winsock_DLL
***************************************************************************
/*--- fun.cpp ---*/
#include "pm.h"//Declare all function
void Help()//when the user input the incorrect parameter show tutorial
{
}
EPARAM CheckParameter(int argc, char* argv[])
//Check the number of external parameter and incept the parameter
{
EPARAM ep;
ep.error = 0;
//First check the number of the parameter
if (argc<4)
{
ep.error = 1;
Help();
return ep;
}
ep.localport = atoi(argv[1]);
ep.addr = inet_addr(argv[2]);
ep.remoteport = atoi(argv[3]);
return ep;
}
int WSA()
{
// Use function WAStartup() to initialize the Winsock DLL
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData))
{
std::cout<<"Start Winsock DLL failed!"<<std::endl;
std::cout<<"Error code: "<<GetLastError()<<std::endl;
return GetLastError();
}
return 0;
}
***************************************************************************
/*--- ResendThread.cpp ---*/
#include "pm.h"//Declare all function
extern EPARAM ExternalParameter;
extern SOCKET sPARAM;
extern int lock;
void Resend(LPVOID param)
{
//Declare two socket
SOCKET sock_c = SOCKET_ERROR;
SOCKET sock_s = SOCKET_ERROR;
//Initialize the sockets
sock_c = sPARAM;//tcp socket connect to client
//When get the sPARAM , unlock the global variable 'lock'
lock = 0;
sock_s = socket(AF_INET, SOCK_STREAM, 0); //tcp socket connect to server
sockaddr_in addr_s;//remote address for connect
addr_s.sin_addr.s_addr = ExternalParameter.addr;
addr_s.sin_family = AF_INET;
addr_s.sin_port = htons(ExternalParameter.remoteport);
//Connect the server use socket sock_s and if success then start the circle
printf("Thread run!/n");
if( connect(sock_s,(sockaddr*)&addr_s,sizeof(addr_s)) == 0 )
{
//Set socket mode to nonblocking
unsigned long cmd;
ioctlsocket(sock_c,FIONBIO,&cmd);
ioctlsocket(sock_s,FIONBIO,&cmd);
//Create socket array
SOCKET socketarray[2];
socketarray[0] = sock_c;
socketarray[1] = sock_s;
//Add the socket to readfds set and writefds set
fd_set fdread;
fd_set fdwrite;
/*************************
//Start resending circle
//The kernel of main project
struct BUF
{
char data[1024*1];
int lock;
};
BUF buf_c;
BUF buf_s;
buf_c.lock = 0;
buf_s.lock = 0;
int slen;
while( GetLastError() == 0 )
{
//Reset the fdread set
FD_ZERO(&fdread);
FD_SET(sock_c,&fdread);
FD_SET(sock_s,&fdread);
//Reset the fdwrite set
FD_ZERO(&fdwrite);
FD_SET(sock_c,&fdwrite);
FD_SET(sock_s,&fdwrite);
if( SOCKET_ERROR != select(0,&fdread,NULL,NULL,NULL) )
{
if( FD_ISSET(sock_c,&fdread) && buf_c.lock == 0 )
{
printf("Sock_c ready!/n");
slen = recv(sock_c,buf_c.data,sizeof(buf_c.data),0);
buf_c.lock = 1;
if( SOCKET_ERROR != send(sock_s,buf_c.data,slen,0) )
{
buf_c.lock = 0;
}
}
if( FD_ISSET(sock_s,&fdread) )
{
printf("Sock_s ready!/n");
slen = recv(sock_s,buf_s.data,sizeof(buf_s.data),0);
buf_s.lock = 1;
if( SOCKET_ERROR != send(sock_c,buf_s.data,slen,0) )
{
buf_s.lock = 0;
}
}
}
}
/*********************
}
printf("Connect abort. Shut off the thread./n");
//std::cout<<"The error code is: "<<GetLastError()<<std::endl;
_endthread();
}