我有两个版本的代码。在一个版本中,如果用户输入短语“GET /index.html”,则服务器会正确响应。在第二个版本中,内置“GET /index.html”短语而不提示用户。第二个版本在从服务器读取响应时挂起,任何想法为什么?
第一版 - 提示用户输入短语
#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;
}
第二版 - 自动发送“GET /index.html” - 这个挂起
#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];
//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;
}
答案 0 :(得分:6)
请求必须以2个回车符和换行符对终止,这在第二个示例中缺失。
char charI[] = "GET /index.html\r\n\r\n";
答案 1 :(得分:1)
请切换到现代版本的HTTP。我觉得很惊讶你的服务器同意回复,因为请求不是远程有效的HTTP。
在您的情况下,这将是一个合适的HTTP / 1.1请求
char charI[] = "GET /index.html HTTP/1.1\r\nHost: vilive.us\r\nConnection: close\r\n\r\n";
请注意Host标头,它允许您与执行虚拟主机的网站进行通信,例如指向相同IP地址的... stackoverflow.com和superuser.com。他们只依靠Host标头来确定用户是否想要访问stackoverflow.com或superuser.com。
此外,您应该在使用套接字后关闭套接字描述符。