各位高手能否帮忙解决一下下面这个程序的问题,while循环时为和会出现服务器无限重发最后一包数据。谢谢了!
#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" );
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下直接执行。谢谢!另如何让连接keep alive?

解决方案 »

  1.   

    while(1)//循环处理
    {}
    条件永远成立,++到最后一个包上,当然无休止的循环发送最后的一包数据了,只要在while循环中加个if语句,判断一下是不是最后一包,如果是最后一包的话,把最后一包发完后跳出来就可以了
      

  2.   

    recv那里有问题,strlen(buftem),........汗!
    下面摘自MSDN。
    If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
      

  3.   

    to0011411:若加判断语句跳出循环,则在实现http代理时浏览器无法显示,因为一跳出程序就结束了,连接强行关闭,而浏览器请求网页时一般都是connection keep-alive.我直接查看浏览器浏览网页时是timewait状态,这个问题如何解决。
    to guxingfeiyu:调试时我用过memset(buf, 0, sizeof(buf));
       n = recv(new_s, buf, sizeof(buf),0);仍是同样的问题这是为什么?并且程序在实际运行时,当服务器发完最后一包后,此时调用select监测与服务器连接的socket状态仍为可读,而此时调用recv()接收仍为最后一包数据,返回成功接收的字节数(不是0),这就是造成无限循环发最后一包的错误所在,但不知如何解决,所以请各位高手帮忙解决一下,谢谢!谢谢各位向我提供了解决问题的方法、提议;
      

  4.   

    我也遇见过类似的问题,重发最后一包可以加控制语句,上面的程序我试运行了,如不加控制浏览器能够打开,但浏览器下的进度条,一直没有显示完毕。可能是程序一直在循环发包的原因,如加控制跳出while循环,则浏览器显示找不到网页,如若在程序中设置最大转发包,如3000,则出现如下情况:在开始时浏览器可以打开,浏览器的状态栏显示为未完成,一会后程序转发到了3000包,程序跳出循环,此时浏览器显示为打不开网页。这是为什么?是因为跳出while循环后程序结束,socket关闭的缘故吗?如果是这样,怎么解决这个问题呢?可以让浏览器完全打开网页显示完毕状态,并使socket保持http请求的keep-alive状态呢?这是我很久以前遗留下来的一个问题,一直没有解决。各位高手帮帮忙,帮忙解决一下这个问题,或者咱们大家可以一起共同探讨一下这个问题!谢谢!