c++: read() Hangs when reading response from server
I have two versions of this code. In one version if the user inputs the phrase "GET /index.html" the server responds properly. In the second version, the "GET /index.html" phrase is built in without prompting the user. The second version hangs when reading a response from the server, any idea why?
First Version - Prompts user for phrase
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[10000];
portno = atoi("85");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error((char *)"ERROR opening socket");
server = gethostbyname("vilive.us");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error((char *)"ERROR connecting");
printf("Please enter the message: ");
memset(buffer,0,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error((char *)"ERROR writing to socket");
memset(buffer,0,256);
n = read(sockfd,buffer,500);
if (n < 0)
error((char *)"ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
Second Version - Automatically sends "GET /index.html" - This one hangs
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, cha开发者_如何学Gor *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[10000];
//TEST
char getI[16];
getI[0]='G';
getI[1]='E';
getI[2]='T';
getI[3]=' ';
getI[4]='/';
getI[5]='i';
getI[6]='n';
getI[7]='d';
getI[8]='e';
getI[9]='x';
getI[10]='.';
getI[11]='h';
getI[12]='t';
getI[13]='m';
getI[14]='l';
getI[15]='\0';
portno = atoi("85");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error((char *)"ERROR opening socket");
server = gethostbyname("vilive.us");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr, (char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error((char *)"ERROR connecting");
/*printf("Please enter the message: ");
memset(buffer,0,256);
fgets(buffer,255,stdin);*/
n = write(sockfd,getI,strlen(getI));
if (n < 0)
error((char *)"ERROR writing to socket");
memset(buffer,0,256);
n = read(sockfd,buffer,500);
if (n < 0)
error((char *)"ERROR reading from socket");
printf("%s\n",buffer);
return 0;
}
The request must be terminated with 2 carriage return and line feed pairs, this is missing in your second example.
char charI[] = "GET /index.html\r\n\r\n";
Please, switch to a modern version of HTTP. I find it amazing that your server agrees to reply, as the request isn't remotely valid HTTP.
This would be a suitable HTTP/1.1 request in your situation
char charI[] = "GET /index.html HTTP/1.1\r\nHost: vilive.us\r\nConnection: close\r\n\r\n";
note the Host header, that allow you to talk with sites that do virtual hosting, like ... stackoverflow.com and superuser.com that points to the same ip address. they only rely on the Host header to figure out if the user want to access stackoverflow.com or superuser.com.
Also, your should close the socket descriptor when you are done using the socket.
精彩评论