我正在尝试用C编写一个Web服务器,我的代码目前是segfaulting,我不知道为什么。它似乎与我的strcats有关,但就我能够得到的而言。我已经发布了代码和gdb输出。任何帮助是极大的赞赏。
*** 代码 ** *
/* web-server.c */
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFLEN 1500
#define BACKLOG 10
static int server_socket(int port) {
int fd;
struct sockaddr_in servaddr;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("Unable to create socket");
return -1;
}
printf("created socket\n");
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(port);
if (bind(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
perror("Unable to bind to port");
return -1;
}
printf("binding completed\n");
if (listen(fd, BACKLOG) == -1){
perror("Unable to listen for connections");
return -1;
}
printf("socket setup\n");
return fd;
}
static char *html_request(char *request) {
char request_code[3], url[BUFLEN], http_code[BUFLEN];
printf(request);
printf("\n");
sscanf(request, "%3s %s %s", request_code, url, http_code);
return url;
}
int main() {
int connfd, servfd, rlen, i, eof;
int content_length = 0;
char buf[BUFLEN];
struct sockaddr_in saddr;
char *response;
char *read_buffer = malloc(1);
char *response200 = "HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: close\nConnection-Length: ";
char *response404 = "HTTP/1.1 404 Not Found\nContent-Type: text/html\nConnection: close\nConnection-Length: ";
FILE *in;
char buffer[1500], content_buffer[5];
char *headers = malloc(BUFLEN);
char *output = malloc(BUFLEN);
socklen_t saddr_len = sizeof(saddr);
servfd = server_socket(8080);
printf("before connection\n");
if ((connfd = accept(servfd, (struct sockaddr *)&saddr, &saddr_len)) == -1) {
perror("Unable to accept connection");
return -1;
}
else {
printf("Accept connection\n");
}
if ((rlen = read(connfd, buf, BUFLEN)) > 0) {
realloc(read_buffer,rlen);
for (i = 0; i < rlen; i++){
printf("%c", buf[i]);
read_buffer[i] = buf[i];
}
printf("\n");
}
printf("IMMA BEAST!\n");
response = html_request(read_buffer);
printf(response);
if (strcmp(response, "/index.html") == 0){
printf("\nMatches!");
in = fopen("index.txt", "r");
if (in == NULL){
printf("Read fail!");
}
while ((eof = fread(buffer, 1, 296, in )) > 0){
content_length = content_length + 1;
}
snprintf(content_buffer, 5, "%d" ,content_length);
headers = strcat(response200, content_buffer);
}
else{
printf("\nFails!");
in = fopen("index-error.txt", "r");
if (in == NULL){
printf("Read fail!");
}
while ((eof = fread(buffer, 1, 300, in )) > 0){
content_length = content_length + 1;
}
snprintf(content_buffer, 5, "%d" ,content_length);
headers = strcat(response404, content_buffer);
}
fclose(in);
output = strcat(headers, buffer);
write(connfd, output, BUFLEN);
close(connfd);
free(read_buffer);
free(headers);
free(output);
return 0;
}
* GDB OUTPUT *
Program received signal SIGSEGV, Segmentation fault.
0x0000003d4647eff0 in strcat () from /lib64/libc.so.6
(gdb) where
#0 0x0000003d4647eff0 in strcat () from /lib64/libc.so.6
#1 0x0000000000400ecd in main ()
(gdb) n
Single stepping until exit from function strcat,
which has no line number information.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
答案 0 :(得分:8)
这根本不行:
strcat("HTTP/1.1 404 Not Found\nContent-Type: text/html\nConnection: close\nConnection-Length: ", content_buffer);
strcat()
将第二个参数附加到第一个参数。第一个参数是一个文字字符串,绝不能修改。 C允许这种编译的唯一原因是,旧代码依赖于char[]
类型的文字字符串而不是const char[]
。
答案 1 :(得分:0)
http://www.manpagez.com/man/3/strcat/
你必须使用正确的大小(第一个字符串的长度+第二个字符串的长度+ 1)来malloc你的第一个字符串。
http://www.manpagez.com/man/3/malloc/
类似的东西:
char *str;
int len = (strlen("HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: close\nConnection-Length: ") + strlen(content_buffer));
str = malloc((len + 1) * sizeof(char));
bzero(str, len);
strcpy(str, "HTTP/1.1 200 OK\nContent-Type: text/html\nConnection: close\nConnection-Length: ");
strcat(str, content_buffer);
str[len] = 0;