请问再和HTTP服务器通讯中:
是不是建立起连接后,可以进行多次的发送和接收
    也就是:
    ......
    connect(sockid,(struct sockaddr *)&server_addr,sizeof(server_addr);
    send(sockid,buffer,sizeof(buffer),0);
    recv(sockid,buf,sizeof(buf),0);
    send(sockid,buffer,sizeof(buffer),0);
    recv(sockid,buf,sizeof(buf),0);
    closesocket(sockid);
请问第二个send()和recv()可以正常工作吗?

解决方案 »

  1.   

    当然可以,但必须加上包头,然后加上Keep-Alive属性.
      

  2.   

    为什么我的第二个recv收不到数据啊?加上包头是什么意思。
    帮我看看我的程序吧,我做的是和代理服务器通讯的,代理服务器要NTLM身份验证。         char buffer[1024];
    CString str;
    int err,rval;
    int ret=0;
    int sockid;
    struct sockaddr_in server_addr;
    struct hostent ;
    memset(buffer,0,sizeof(buffer));
    WSADATA ws;
    err = WSAStartup(MAKEWORD(1,1),&ws);
    if(err != 0)
    {
    MessageBox("wrong in startup ");
    return;
    }
    sockid = socket(AF_INET,SOCK_STREAM,0);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.S_un.S_un_b.s_b1 = 192;
    server_addr.sin_addr.S_un.S_un_b.s_b2 = 188;
    server_addr.sin_addr.S_un.S_un_b.s_b3 = 10;
    server_addr.sin_addr.S_un.S_un_b.s_b4 = 1;
    server_addr.sin_port = htons(80);
    if(connect(sockid,(struct sockaddr *)&server_addr,sizeof(server_addr))<0)
    {
    MessageBox("connecting is wrong");
    return;
    } str = "GET http://www.sina.com.cn/ HTTP/1.0\r\n";
    str += "Host: www.sina.com.cn\r\n";
    str += "Accept: */*\r\n";
    str += "Accept-Language: zh-cn\r\n";
    str += "User-Agent: test\r\n";
    str += "Proxy-Connection: Keep-Alive\r\n";
    str += "Pragma: no-cache\r\n";
    str += "Cache-Control: no-cache\r\n";
    str += "\r\n";

    send(sockid,str.GetBuffer(str.GetLength()) ,str.GetLength(),0);
    str.ReleaseBuffer();
    rval = recv(sockid,buffer,1024,0);
    MessageBox(buffer);
    if((buffer[9]=='4')&&(buffer[10]=='0')&&(buffer[11]='7'))
    {

    //
    CString domain = "PRIDOMAIN";
    CString host = "mycomputer";
       //构造第一次握手所需认证的NTLM信息
    struct type_1_message message1;
    message1.protocol[0]='N';
    message1.protocol[1]='T';
    message1.protocol[2]='L';
    message1.protocol[3]='M';
    message1.protocol[4]='S';
    message1.protocol[5]='S';
    message1.protocol[6]='P';
    message1.protocol[7]='\0';
    message1.type = 0x01;
    message1.zero1[0] = 0;
    message1.zero1[1] = 0;
    message1.zero1[2] = 0;
    message1.flags.short_char = (short)0xb203;
    message1.zero2[0] = 0;
    message1.zero2[1] = 0xa0;     //&acute;&Euml;&acute;&brvbar;&sup2;&raquo;&Iacute;&not;&Oacute;&Uacute;
    message1.dom_len1.short_char = domain.GetLength();
    message1.dom_len2.short_char = domain.GetLength();
    message1.host_len1.short_char = host.GetLength();
    message1.host_len2.short_char = host.GetLength();
    message1.host_off.short_char = 32;
    message1.dom_off.short_char = message1.host_off.short_char + message1.host_len1.short_char;
    message1.zero3[0] = 0;
    message1.zero3[1] = 0;
    message1.zero4[0] = 0;
    message1.zero4[1] = 0;
    message1.host = host.GetBuffer(host.GetLength());
    message1.dom = domain.GetBuffer(domain.GetLength());
    //ecoding the message1
    CByteArray array_sr,array_ds;
    for(int i=0; i<8; i++)
    array_sr.Add(message1.protocol[i]);
    array_sr.Add(message1.type);
    for(i=0; i<3; i++)
    array_sr.Add(message1.zero1[i]);
    array_sr.Add(message1.flags.int_char.byte_hig );
    array_sr.Add(message1.flags.int_char.byte_low );
    array_sr.Add(message1.zero2[0]);
    array_sr.Add(message1.zero2[1]); array_sr.Add(message1.dom_len1.int_char.byte_hig);
    array_sr.Add(message1.dom_len1.int_char.byte_low);
    array_sr.Add(message1.dom_len2.int_char.byte_hig);
    array_sr.Add(message1.dom_len2.int_char.byte_low);
    array_sr.Add(message1.dom_off.int_char.byte_hig);
    array_sr.Add(message1.dom_off.int_char.byte_low);
    for(i=0;i<2;i++)
    array_sr.Add(message1.zero2[i]); array_sr.Add(message1.host_len1.int_char.byte_hig);
    array_sr.Add(message1.host_len1.int_char.byte_low);
    array_sr.Add(message1.host_len2.int_char.byte_hig);
    array_sr.Add(message1.host_len2.int_char.byte_low);
    array_sr.Add(message1.host_off.int_char.byte_hig);
    array_sr.Add(message1.host_off.int_char.byte_low);
    for(i=0;i<2;i++)
    array_sr.Add(message1.zero2[i]); for(i=0; i<host.GetLength(); i++)
    array_sr.Add(message1.host[i]);
    for(i=0; i<domain.GetLength(); i++)
    array_sr.Add(message1.dom[i]); //CODEBASE 64 加密
    CBase64Coding base64coding;
    if(!base64coding.Encode(array_sr,array_ds))
    MessageBox("wrong in encoding"); CString base64str1 ,str1,str2;
    for(i=0; i<array_ds.GetSize(); i++)
    base64str1 +=array_ds.GetAt(i);//构造HEAD
    str = "GET http://www.sina.com.cn/ HTTP/1.0\r\n";
    str += "Host: www.sina.com.cn\r\n";
    str += "Accept: */*\r\n";
    str += "Accept-Language: zh-cn\r\n";
    str += "User-Agent: test\r\n";
    str += "Proxy-Authorization: NTLM ";
    str += base64str1;
    str += "\r\n";
    str += "Proxy-Connection: Keep-Alive\r\n";
    str += "Pragma: no-cache\r\n";
    str += "Cache-Control: no-cache\r\n";
    str += "\r\n";

    send(sockid,str.GetBuffer(str.GetLength()) ,str.GetLength(),0);
    str.ReleaseBuffer();
    memset(buffer,0,1024);
    recv(sockid,buffer,1024,0);
    MessageBox(buffer); } closesocket(sockid);
    WSACleanup();就是这个第二个recv()函数接收不到东西,也就是第二个MessageBox(buffer)后,什么也没有显示。
      

  3.   

    str = "GET http://www.sina.com.cn/ HTTP/1.0\r\n";
    str += "Host: www.sina.com.cn\r\n";
    str += "Accept: */*\r\n";
    str += "Accept-Language: zh-cn\r\n";
    str += "User-Agent: test\r\n";
    str += "Proxy-Connection: Keep-Alive\r\n";
    str += "Pragma: no-cache\r\n";
    str += "Cache-Control: no-cache\r\n";
    str += "Connection: Keep-Alive\r\n";
    str += "\r\n";
      

  4.   

    还是不行!!有一个疑问就是,是不是在第一个recv()函数时,如果开的buffer[1024]较小(小于HTTP返回的数据量设为3675)必须进行多次recv()函数把所有的数据接收完,才能进行下一步send()函数啊?
      

  5.   

    我发现第二个send()后的recv()接收到的数据,是第一次HTTP代理服务器返回的而第一个recv()没有接收完的数据。但是我把第一个recv()改写为:
                       rval = recv(sockid,1024,0);
                       while(rval != 0)
                     {
                          rval = recv(sockid,1024,0);
                     }
    后,第二个recv()就又收不到任何东西了.郁闷中,请继续关注
      

  6.   

    socket是流,你要根据http头Content-Length或Chunk的大小决定读多少。后边的就是下一个请求的回应
      

  7.   

    还是不可以啊.我看了返回来的头Content_length:3675
    但是我在接收3675个字节的数据后,后面仍然有数据,此时第二个send()还没有调用.我此时发送第二个send(),然后recv()发现,此时接收的数据,好像仍然是上一个send()后返回的结构!!!!!!!!!!!!
      

  8.   

    你没有开多线程吧?
    要知道,HTTP这烂东西,它是把很多客户请求用一个SOCKET传输的.比如你别的线程里有数据请求,虽然你有两个SOCKET连接,但服务器有可能会把它们从一个SOCKET里发过来.
    你的RECV有问题啊,一次recv根本不可能保证你把数据收完,写成这样.BOOL RecvData(SOCKET s, char *data, int len)
    {
    char * p = data;
    int i = 0;
    int k = len;
    int ret = 0; if(len <= 0)
    {
    return TRUE;
    } while(1)
    {
    ret = recv(s,p,k,0);
    if(ret == 0 || ret == SOCKET_ERROR)
    {
    TRACE("RecvData OUT,%d\n",WSAGetLastError());
    return FALSE;
    }
    i += ret;
    p += ret;
    k -= ret;
    if(i >= len)
    {
    break;
    }
    }
    return TRUE;
    }