我完全不熟悉网络编程。所以,我的工作是通过这样的插座上的一个程序,并尝试读取HTML内容(我认为这是在HTML,有人纠正我在这个):C recv()不在缓冲区中读取
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;
}
通常嫌疑犯:治疗缓冲区作为空终止字符数组时,不能保证如此。未能正确处理recv()返回的结果。 –
对于其中一个,'sendRequest'中的'send'调用中的'sizeof(request)'并不是按照您的想法进行的。当请求变量作为参数传递时,request变量是一个通过转换的指针,而不是来自调用者的数组,因此sizeof会正确地给出你所要求的:指针的大小。还有次要的,但它仍然不应该发生,没有'Open_clientfd',但有'open_clientfd'。 – WhozCraig
..如果您正在考虑针对@WhozCraig评论达成strlen(),请再考虑一次。将希望发送的字节数作为单独的参数传递。 –