用winsocket实现http代理问题

一个代理程序的简单实现流程为:

代理服务器创建socket--->绑定socket--->监听socket--->accept--->成功时再创建一新的socket与http服务器端进行连接请求(connect)--->与服务器端连接成功后调用select函数查看socket状态,如过与客户端连接的socket有数据读,则读出该数据并向服务器端转发该报文,同理如果与服务器端连接的socket有数据读,则读出该数据向客户端转发。

相关程序如下:该程序可以实现在服务器端和客户端转发包的功能,

#include "stdafx.h"
#include <stdio.h>
#include <Winsock2.h>
#include <signal.h>
#include <iostream.h>
#include <Windows.h>
#include <io.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
int main(int argc, char* argv[])
{
  struct sockaddr_in address,address1;
  int i,j,s,s1,tn[4]={0};
  int err;
  int new_s,n1;
  int n=0;
  int ret;
  struct timeval t2;
  char buf[1000],buftem[1000];
  int optLen = sizeof(int);
  fd_set r, w, e;
  WORD wVer;
  WSADATA wsaData;
  wVer=MAKEWORD(1,1);
  err=WSAStartup(wVer,&wsaData);//判断Windows sockets dll版本,初始化
  if(err!=0)   
 return(0);

  s = socket (AF_INET, SOCK_STREAM, 0);//创建socket
  if (s == -1)
  {j=WSAGetLastError();
   return -1;
  }
 
  i = 1;
  address.sin_family = AF_INET;
  address.sin_port = htons (8000);//监听端口8000 

 address.sin_addr.s_addr = INADDR_ANY;
  if (bind (s, (struct sockaddr *)&address, sizeof (address)) == -1)
    {
      return -1;
    }

  if (listen (s, 1) == -1)//监听,设置监听队列为1,为了简化程序
    {
      return -1;
    }
  printf("正在等待请求,请稍后。。。。。。/n");
new_s=accept(s,NULL,NULL);//accept客户端连接,new_s是用于代理和客户端的连接
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建新连接,用于连接http服务器
address.sin_family=AF_INET;
address.sin_addr.s_addr = inet_addr( "127.0.0.1" );//http服务器ip地址
address.sin_port = htons( 80 );


if (ConnectSocket!=INVALID_SOCKET)
{
 printf("socket创建/n");

 int nn=connect( ConnectSocket, (SOCKADDR*) &address, sizeof(address) );}//进行连接
while(1)//循环处理
  {
  FD_ZERO (&r);
  FD_ZERO (&w);
  FD_ZERO (&e); 
  FD_SET(new_s,&r);
  FD_SET(new_s,&w);
  FD_SET(new_s,&e);
  FD_SET(ConnectSocket,&r);
  FD_SET(ConnectSocket,&w);
  FD_SET(ConnectSocket,&e);
  t2.tv_sec=5;
  t2.tv_usec=5*1000;
  ret=select(new_s+1,&r,&w,&e,NULL);//查看socket状态
  if(FD_ISSET(new_s,&r))//如果客户端发送数据包,则接收并转发服务器端
  {  
   n = recv(new_s, buf, strlen(buf),0);
   if(n!=-1)
   {
    tn[0]++;
    printf("这是从客户端收到的第%d包,内容是:%s,/n报文长度:%d./n",tn[0],buf,n);//打印相关信息用于调试
    n1=send(ConnectSocket,buf,n,0);
    if(n1!=-1)
    {
     tn[1]++;
        printf("向服务器端转发报文数%d,转发报文长度%d/n",tn[1],n1);
    }
   }
  }
   if(FD_ISSET(ConnectSocket,&r))//如果服务器端发送数据包,接收并转发客户端
   { 

    n1=recv(ConnectSocket,buftem,strlen(buftem),0);
    if(n1!=-1)
    {
     tn[2]++;
     printf("这是从服务器端收到的第%d包,内容是:%s,报文长度是:%d./n",tn[2],buftem,n1);
     if(FD_ISSET(new_s,&w))
     //strcat(buftem,"#13#10");
     {n = send(new_s, buftem,n1,0);
     if(n!=-1)
     {
      tn[3]++;
      printf("向客户端转发报文数%d,转发报文长度%d./n",tn[3],n);
     //if(tn[3]==50)///此处因为程序会无限循环发报,所以设置一最大转发包进行控制
     //{break;}
     }
     }
     //Sleep(200);
    }
   }
  }
}

程序可以在vc环境中直接执行(新建工程的时候选择控制台),运行时如将break语句去掉则能在浏览器中打开所需网页,但此刻服务器一直在重发最后一包数据(此时客户端已收到最后一包数据,转发中间包时没有这个问题),请问这是为什么?另当数据包转发完毕后如何将连接保持keep alive?如一直保持while循环则很耗资源反之若终止while循环则连接关闭,浏览器将显示无法打开网页。我查看了一些tcp连接发现还有个timewait状态,这是怎么实现的?希望各位高手能给个建议或解决的方法,谢谢了!我的QQ是264116549,如有需要可以和我QQ.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值