我是看recv返回是 SOCKET_ERROR或0 我就关闭socket,这似乎有点问题?
retval = recv(http服务器 );
if (retval == SOCKET_ERROR || retval == 0) 
closesocket(socket);

解决方案 »

  1.   

    在下写过这样的程序.
    但我的思路与你不同,根本不用去想http服务器是不是与我关闭了连接.因为.http服务器是与客户的交流是回合制的.
    就是说用户连接服务器.然后发送请求,服务器返回结果.然后连接就关闭了.
    之后你再要要求的话,就要再连接,再发请求..所以.我会写好一个函数:连接->发送->接收 一条龙服务.
    用起来就这样就行了.
    const char packdate0[]="GET /getimage?0.26983277278867457 HTTP/1.1\r\nAccept: */*\r\nReferer: http://freeqq2.qq.com/nom_reg.shtml\r\nAccept-Language: zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\nHost: freeqq3.qq.com\r\nConnection: Keep-Alive\r\nCookie: ";
    //用来放get GIF的请求.
    int responselen=sendToHostAndRecv(host0,post,(char *)packdate0,strlen(packdate0),&response);
     if (responselen<0)//返回值小于0.失败.
    {MY_SHOW("\r\nin<getQQ> after sub sendToHostAndRecv return content small than 0.\r\n");
    // delete [] host1;delete [] host2;delete []response;
        // return;
     goto goto_end;
    }
    相关函数:
    int sendToHostAndRecv(char * host,int post,char * date,int datelen,char **buff)
    //将Date所指向的数据发到host:post中.host date所指的内存要事先分配好.
    //函数在buff中返回服务器host中返回的数据.
    {//MY_SHOW("\r\n");
     //MY_SHOW(date); 
     SOCKET socket1=NULL;
     socket1=ConnectToServer(host,post);
     if (socket1==NULL)
    {MY_SHOW("\r\nin<sendToHostAndRecv>after ConnectToserver .return NULL.\r\n");
     return -1;
    }
    if (send(socket1,date,datelen,0)==SOCKET_ERROR)
       {MY_SHOW("\r\nin<sendToHostAndRecv>after winsock API send .return SOCKET_ERROR.\r\n");
     return -2;
    }
     int i=receDate(socket1, buff);
     if (i<=0)
    {MY_SHOW("\r\nin<sendToHostAndRecv>after Sub receDate ..return size of buff small than 0.\r\n");
       //delete [] *buff;
    return -3;
    }
    //MYENTER;
    //MY_SHOW(*buff);
    return i;
    }int receDate(SOCKET socket1,char ** date )
    {
     int preTotal=0,curTotal=0,curSize=0,i=0;
     char strTemp[MAXSOCKETRECV_SIZE];
     char * str1=NULL;char *str2=NULL; while(1)

          curSize=recv(socket1,(char *)strTemp,(MAXSOCKETRECV_SIZE-1),0);
      if ((curSize==SOCKET_ERROR) || (curSize<=0))
    {
      break;
    }
          
      curTotal=preTotal+curSize;
      str2=new char[curTotal+1];
      if (str2==NULL)
    {
     return -1;
    }
      i=0;
      while (i<preTotal)
    {
      str2[i]=str1[i];
      i++;
    }
      delete [] str1;
      str1=&str2[i];
      i=0;
          while (i<curSize)
    {
      str1[i]=strTemp[i];
      i++;
    }
      str1[i]=0;
      str1=str2;
      preTotal=curTotal; };
     *date=str1;
     return curTotal;  
    }#define MAXSOCKETRECV_SIZE 1024bool sendDate(SOCKET socket1,char * date)
    {
    if (send(socket1,date,strlen(date),0)==SOCKET_ERROR)
       return false;
    return true;
    }SOCKET ConnectToServer(char * SerNameOrIp,int port)
    {
     if (strlen(SerNameOrIp)==0)
     return NULL;
    SOCKADDR_IN Server_info;
     
      SOCKET socket1=NULL;  socket1=socket(AF_INET,SOCK_STREAM,0);
      if (socket1==INVALID_SOCKET)
      {MY_SHOW("\r\n---can not crearte a socket\r\n");
       return NULL;
      }
       Server_info.sin_family=AF_INET;
      Server_info.sin_port=htons(port);//get port
      struct hostent  * heServHostInfo=NULL;
      heServHostInfo=gethostbyname((const char FAR *)SerNameOrIp);//get IP
     /* char ppp[1024];
      wsprintf(ppp,"\r\nSerNameOrIp=%s.\r\n",SerNameOrIp);
      MY_SHOW(ppp);*/
      if (heServHostInfo==NULL)//SerNameOrIP is IP or other wrong.
    { //MY_SHOW("\r\nSeraNameOrIp is Ip or other wrong");
      unsigned long lTemp=0;
          lTemp=inet_addr(SerNameOrIp);
      if (lTemp==INADDR_NONE)
      {closesocket(socket1);
       MY_SHOW("\r\n can not get the sever IP\r\n");
       return NULL;
      }
      else
        Server_info.sin_addr.S_un.S_addr=lTemp;
     
    }
      else//SerNaveOrIp is Name ..*((long *)(heServHostInfo->h_addr))
    { // MY_SHOW("\r\nSeraNameOrIp is Name\r\n");
       Server_info.sin_addr.S_un.S_addr=*((long *)(heServHostInfo->h_addr));
     }
    //MY_SHOW("\r\n----------------\r\n");
      if (connect(socket1,(sockaddr *)&Server_info,sizeof(Server_info))==SOCKET_ERROR)
          {if (WSAGetLastError()!=WSAEWOULDBLOCK)
              {closesocket(socket1);
          //myDisConnect();
              MessageBox(myHwnd,"无法联到服务器" ,"不好意思",MB_OK | MB_ICONWARNING);
      return NULL;
      }
    }
    return socket1;
    }
      

  2.   

    1.服务器关闭连接,recv应该返回0,没问题吧?
    2.出现某些网络故障,recv返回SOCKET_ERROR
      其中WSA_IO_PENDING这种错误可以忽略?
    3.HTTP/1 回合制 这样比较耗资源;HTTP/1.1,多个交互可在单个连接上处理。