C中发送HTTP请求和获取响应时的分段错误
我制作了一个连接到服务器的客户端套接字。然后我想向它发送HTTP请求C中发送HTTP请求和获取响应时的分段错误,c,sockets,segmentation-fault,client,C,Sockets,Segmentation Fault,Client,我制作了一个连接到服务器的客户端套接字。然后我想向它发送HTTP请求 GET /index.html HTTP/1.1\r\n Host: www.google.com\r\n \r\n 这是我的代码: #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #includ
GET /index.html HTTP/1.1\r\n
Host: www.google.com\r\n
\r\n
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MAX 4096
int main(int argc, char **argv){
char *host;
strcpy(host, argv[1]);
char *request = "GET ";
strcat(request, argv[3]);
strcat(request, " HTTP/1.1\r\nHost: ");
strcat(request, argv[2]);
strcat(request, "\r\n\r\n");
char *response;
int port;
port = atoi(argv[2]);
int sockfd;
struct sockaddr_in servaddr;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("Failed to create socket!");
exit(1);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
struct hostent *server;
server = gethostbyname(host);
if (server == NULL) perror("Failed to get host name!");
memcpy(&servaddr.sin_addr.s_addr, server->h_addr, server->h_length);
if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){
perror("Failed to connect!");
exit(1);
}
while(fgets(request, MAX, stdin) != NULL){
send(sockfd, request, strlen(request), 0);
if(recv(sockfd, response, MAX, 0) == 0){
perror("Failed to recieve!");
exit(1);
}
printf("Response:/n");
fputs(response, stdout);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大值4096
int main(int argc,字符**argv){
字符*主机;
strcpy(主机,argv[1]);
char*request=“GET”;
strcat(请求,argv[3]);
strcat(请求,“HTTP/1.1\r\nHost:”;
strcat(请求,argv[2]);
strcat(请求“\r\n\r\n”);
字符*响应;
国际港口;
端口=atoi(argv[2]);
int-sockfd;
servaddr中的结构sockaddr_;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
perror(“创建套接字失败!”);
出口(1);
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sinu端口=htons(端口);
结构主机*服务器;
服务器=gethostbyname(主机);
if(server==NULL)perror(“获取主机名失败!”);
memcpy(&servaddr.sin\u addr.s\u addr,server->h\u addr,server->h\u length);
if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0{
perror(“连接失败!”);
出口(1);
}
while(fgets(请求、最大值、标准输入)!=NULL){
发送(sockfd,请求,strlen(请求),0);
如果(recv(sockfd,响应,最大值,0)=0){
perror(“接收失败!”);
出口(1);
}
printf(“响应:/n”);
FPUT(响应、标准输出);
}
当我运行它时,它得到了一个分段错误。然后我使用GDB来跟踪它
#0 strcmp () at ../sysdeps/x86_64/multiarch/../strcmp.S:132
#1 0x00007ffff7deb1a5 in _dl_name_match_p (name=0x4004e9 "libc.so.6", map=0x7ffff7ffe1c8) at dl-misc.c:289
#2 0x00007ffff7de402f in do_lookup_x (new_hash=new_hash@entry=479433942, old_hash=old_hash@entry=0x7fffffffe950,
result=result@entry=0x7fffffffe960, scope=<optimized out>, i=<optimized out>, i@entry=0, flags=flags@entry=1,
skip=skip@entry=0x0, undef_map=undef_map@entry=0x7ffff7ffe1c8) at dl-lookup.c:462
#3 0x00007ffff7de4961 in _dl_lookup_symbol_x (undef_name=0x40056b "strcat", undef_map=0x7ffff7ffe1c8,
ref=ref@entry=0x7fffffffea18, symbol_scope=0x7ffff7ffe520, version=0x7ffff7ff9a10, type_class=type_class@entry=1, flags=1,
skip_map=skip_map@entry=0x0) at dl-lookup.c:737
#4 0x00007ffff7de9527 in _dl_fixup (l=<optimized out>, reloc_arg=<optimized out>) at ../elf/dl-runtime.c:111
#5 0x00007ffff7df04d5 in _dl_runtime_resolve () at ../sysdeps/x86_64/dl-trampoline.S:45
#6 0x0000000000400b18 in main ()
#0 strcmp()位于../sysdeps/x86_64/multiarch/。/strcmp.S:132
#1 0x00007FF7FF7DEB1A5位于dl misc.c:289处的匹配(名称=0x4004e9“libc.so.6”,映射=0x7FF7FFE1C8)
#2 0x00007FF7DE402F在do_查找_x中(新_哈希=新)_hash@entry=479433942,old_hash=old_hash@entry=0x7FFFFFE950,
结果=result@entry=0x7FFFFFE960,作用域=,i=,i@entry=0,标志=flags@entry=1,
跳过=skip@entry=0x0,未定义映射=未定义_map@entry=0x7ffff7ffe1c8)在dl查找处。c:462
#3 0x00007FF7DE4961在查找符号中(未定义名称=0x40056b“strcat”,未定义映射=0x7FF7FF1C8,
参考号=ref@entry=0x7FFFFFEA18,符号范围=0x7FFFF7FF520,版本=0x7ffff7ff9a10,类型=type_class@entry=1,标志=1,
跳过映射=跳过_map@entry=0x0)在dl查找时。c:737
#4 0x00007ffff7de9527位于../elf/dl运行时的_dl_fixup(l=,reloc_arg=)中。c:111
#5 0x00007FF7DF04D5位于../sysdeps/x86\u 64/dl trampoline的运行时解析()中。S:45
#主管道中的6 0x0000000000400b18()
这个错误消息真的让我很困惑。我到底在哪里犯了错误
char *request = "GET ";
/* you can't do this */
strcat(request, argv[3]);
strcat(request, " HTTP/1.1\r\nHost: ");
strcat(request, argv[2]);
strcat(request, "\r\n\r\n");
由于request
指向常量字符串,您无法向其追加更多字符。您需要为其分配更多内存,然后向其追加更多字符串
类似于响应
。在将数据读入之前为其分配内存
一般而言,添加
request = malloc(sizeof(char) * MAX);
response = malloc(sizeof(char) * MAX);
然后
为了安全起见,最好使用
strncat
etc功能。host
和request
不指向可写内存缓冲区。您不能对其使用strcpy
、strcat
或任何其他写入操作。例如,您需要使用malloc
来分配内存。并小心使用argv[2]
参数,因为:strcat(请求,argv[2])
和port=atoi(argv[2]);
所以argv[2]
是主机还是argv[2]
是端口?谢谢!这真的很有帮助。
strcpy(request, "GET ");
strcat(request, argv[3]);
strcat(request, " HTTP/1.1\r\nHost: ");
strcat(request, argv[2]);
strcat(request, "\r\n\r\n");