端口转发代码

这个程序是我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();

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值