C recv()没有在缓冲区中读取

时间:2015-08-08 15:56:41

标签: c sockets network-programming

我对网络编程完全陌生。所以我正在研究一个将这样的东西传递给套接字的程序,并尝试用HTML阅读内容(我认为它是用HTML编写的,有人在此纠正我):

GET infolab.stanford.edu/~ullman/focs.html HTTP/1.1\r\n 
Host: www.google.com\r\n 
\r\n

infolab.stanford.edu/~ullman/focs.html是我试图阅读的网站。

所以我将GET消息存储在字符串中,然后使用send()方法将请求发送到服务器。我检查了errno并返回Success

然后我使用recv()来读取内容并将其存储在缓冲区中。我做了一些谷歌搜索,发现缓冲区[6000]就像一个标准。

但是,我的程序需要永远运行recv()。 errno返回Success,但是当我尝试打印缓冲区时,它只是一个空行。

int open_clientfd(char *hostname, int port)
{
   int clientfd;
   struct hostent *hp;
   struct sockaddr_in serveraddr;

   if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
      return -1; /* Check errno for cause of error */

   /* Fill in the server's IP address and port */
   if ((hp = gethostbyname(hostname)) == NULL)
      return -2; /* Check h_errno for cause of error */
   bzero((char *) &serveraddr, sizeof(serveraddr));
   serveraddr.sin_family = AF_INET;
   bcopy((char *)hp->h_addr_list[0],
         (char
          *)&serveraddr.sin_addr.s_addr,
         hp->h_length);
   serveraddr.sin_port = htons(port);

   /* Establish a connection with
    * the server */
   if (connect(clientfd, (SA *)
            &serveraddr,
            sizeof(serveraddr)) < 0)
      return -1;
   return clientfd;
}

void sendRequest(int clientfd, char request[128]) {
   char buffer[6000];
   int byteSent, byteRead;

   // send request
   byteSent = send(clientfd, request, sizeof(request), 0);
   fprintf(stderr, "%s\n", strerror(errno));

   // read
   byteRead = recv(clientfd, buffer, sizeof(buffer), 0);
   fprintf(stderr, "%s\n", strerror(errno));

   fprintf(stdout, "%s\n", buffer);
}

int main(int argc, char **argv) {
   int clientfd, port;
   char *host, *fileURL;

   rio_t rio;

   host = argv[1];
   fileURL = argv[2];

   port = atoi(argv[3]);

   clientfd = open_clientfd(host, port);

   // set up request string
   char request[128]; 

   // ....

   // now request stores the string above

   sendRequest(clientfd, request);

   return 0;
}

1 个答案:

答案 0 :(得分:3)

您的请求设置错误。首先,您发送的数据相当于指针的大小,而不是请求缓冲区。其次,请求GET不应包含站点名称;用于建立连接。

您的设置和调用的精简版本如下所示。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>

int open_clientfd(char *hostname, int port)
{
    int clientfd;
    struct hostent *hp;
    struct sockaddr_in serveraddr;

    if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return -1; /* Check errno for cause of error */

    /* Fill in the server's IP address and port */
    if ((hp = gethostbyname(hostname)) == NULL)
        return -2; /* Check h_errno for cause of error */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    bcopy((char *)hp->h_addr_list[0],
          (char *)&serveraddr.sin_addr.s_addr,
          hp->h_length);
    serveraddr.sin_port = htons(port);

    /* Establish a connection with the server */
    if (connect(clientfd, (const struct sockaddr*)
                &serveraddr,
                sizeof(serveraddr)) < 0)
        return -1;
    return clientfd;
}

void sendRequest(int clientfd, char request[], size_t rlen)
{
    ssize_t byteSent, byteRead;

    // send request
    byteSent = send(clientfd, request, rlen, 0);
    if (byteSent < 0)
    {
        fprintf(stderr, "%s\n", strerror(errno));
        return;
    }

    // read response
    do
    {
        char buffer[1024];
        byteRead = recv(clientfd, buffer, sizeof(buffer)-1, 0);
        if (byteRead < 0)
        {
            fprintf(stderr, "%s\n", strerror(errno));
            return;
        }

        buffer[byteRead] = 0;
        fprintf(stdout, "%s", buffer);

    } while (byteRead > 0);
}

int main(int argc, char **argv)
{
    int clientfd = open_clientfd("infolab.stanford.edu", 80);
    if (clientfd < 0)
    {
        perror(NULL);
        return EXIT_FAILURE;
    }

    // set up request string
    char request[] = "GET /~ullman/focs.html HTTP/1.1\r\n"
                     "Host: www.google.com\r\n"
                     "\r\n";

    // now request stores the string above
    sendRequest(clientfd, request, sizeof(request)-1);
    close(clientfd);

    return 0;
}

<强>输出

HTTP/1.1 200 OK
Date: Sat, 08 Aug 2015 16:24:56 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Wed, 17 Mar 2010 21:53:56 GMT
ETag: "3448c4fe-f93-269bc500"
Accept-Ranges: bytes
Content-Length: 3987
Content-Type: text/html; charset=UTF-8

<TITLE>Aho/Ullman Foundations of Computer Science</TITLE>

<BODY BGCOLOR = "E0F7F0">

<CENTER><TABLE>
<TR><TD><IMG SRC = "gifs/focs.gif"></td>
<TD ALIGN = MIDDLE><FONT SIZE = 6>Foundations of Computer
Science</font></td></tr>
<TR></tr>
</TABLE></CENTER>
<P>
This book has been taken out of print by W. H. Freeman.
You are welcome to use it if you like.
We believed in 1992 it was the way to introduce theory in
Computer Science, and we believe that today.
<P>
<CENTER>--- Al Aho and Jeff Ullman</center>
<P>
<H3>Index</H3>
<P>
<A href="#pdfs">The Book</a> |
<A href="#supp">Materials</a> |
<A href="#grad">Gradiance</a> |
<A href="#errata">Errata</a>

<A name="pdfs"></a>
<H3>PDF's of the Book</H3>
<P>
<UL>
<LI><A href="focs/preface.pdf">Preface</a>
<LI><A href="focs/toc.pdf">Table of Contents</a>
<LI><A href="focs/ch01.pdf">Chapter 1</a> Computer Science: The
Mechanization of Abstraction
<LI><A href="focs/ch02.pdf">Chapter 2</a> Iteration, Induction, and
Recursion
<LI><A href="focs/ch03.pdf">Chapter 3</a> The Running Time of Programs
<LI><A href="focs/ch04.pdf">Chapter 4</a> Combinatorics and Probability
<LI><A href="focs/ch05.pdf">Chapter 5</a> The Tree Data Model
<LI><A href="focs/ch06.pdf">Chapter 6</a> The List Data Model
<LI><A href="focs/ch07.pdf">Chapter 7</a> The Set Data Model
<LI><A href="focs/ch08.pdf">Chapter 8</a> The Relational Data Model
<LI><A href="focs/ch09.pdf">Chapter 9</a> The Graph Data Model
<LI><A href="focs/ch10.pdf">Chapter 10</a> Patterns, Automata, and
Regular Expressions
<LI><A href="focs/ch11.pdf">Chapter 11</a> Recursive Description of
Patterns
<LI><A href="focs/ch12.pdf">Chapter 12</a> Propositional Logic
<LI><A href="focs/ch13.pdf">Chapter 13</a> Using Logic to Design
Computer Components
<LI><A href="focs/ch14.pdf">Chapter 14</a> Predicate Logic
<LI><A href="focs/index.pdf">Index</a>
</ul>

<A name="supp"></a>
<H3>Supplementary Materials</H3>
<P>
<UL>
<LI><A HREF = "pub/sols-fcsc-new.ps">Solutions to Selected Exercises</a>
<LI><A HREF = "fcs-exams.html">A Selection of Exams and Projects</A>
<LI><A HREF = "fcsc-notes.html">Jeff Ullman's Lecture Notes</A>
(ancient)
<LI><A HREF = "fcsc-figures.html">The Programs Appearing in the Book</a>
</ul>

<A name="grad"></a>
<H3>Gradiance Package Available</H3>

<P>
<A href="http://www.gradiance.com">Gradiance</a>
is offering a free trial of its automated homeworks for the topics
covered by this book.  These homeworks are designed as a teaching aid
rather than an assessment tool.  Students get advice when they make a
mistake and are encouraged to try working on the same problem(s) until
they get them right.  If you would like to try the system gratis for
your class, make yourself an account at <A
href="http://www.gradiance.com/services"><TT>www.gradiance.com/services</tt></a>.
Then, send email to sup port @grad iance .com (ignore the blanks in that
email address, of course) telling us your login and that you would like
to try the discrete-math product.  You can find manuals for
instructors, students, and question-authors at <A
href="http://www.gradiance.com/info.html"><TT>www.gradiance.com/info.html</tt></a>.
<P>
<B>Special offer for students</b>:  Until June 30, 2009, we have made use of the
Gradiance materials available for students whose instructors are not using
the system.  Make yourself an account on
<A href="http://www.gradiance.com/services"><TT>www.gradiance.com/services</tt></a>,
and then sign up for the class 8CD5ED01.  You will be able to work 31 selected
homeworks, and will get advice when you make an error.  The only difference is that
we cannot reveal solutions, because these assignments are open indefinitely.

<A name="errata"></a>
<H3>Errata Sheet</H3>

We are going to try to maintain errata.  Please see
<A href="focs/errata.html">The Errata Sheet</a>.
If you find an unreported error, please send email to ullman
at gmail dot com.

<!-- -->
<script src="http://tags.stanford.edu/tags.js" type="text/javascript"></script>
<!-- -->

</BODY>