C中发送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

我制作了一个连接到服务器的客户端套接字。然后我想向它发送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>
#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");