C语言开发tinyWeb服务器浏览器访问无限加载故障排查求助
问题排查与修复方案
1. send_string函数致命语法错误
send_string函数中if(sent_bytes == -1);后面多了一个分号,会导致无论send调用是否报错,第一次循环都会直接执行return 0,永远走不到后续的printf("ALL BYTES SENT\n")逻辑。
修复代码:
int send_string(int sockfd, unsigned char *buffer){ int sent_bytes, bytes_to_send; bytes_to_send = strlen(buffer); while(bytes_to_send > 0){ sent_bytes = send(sockfd, buffer, bytes_to_send, 0); if(sent_bytes == -1) // 移除多余分号 return 0; bytes_to_send -= sent_bytes; buffer += sent_bytes; } printf("ALL BYTES SENT\n"); return 1; }
2. recv_line函数逻辑完全错误
- 头文件中
EOL_SIZE未赋值,EOL定义为\r\n长度为2,需补充赋值 - 匹配失败后重置
eol_match的代码误写为双等号比较,应为赋值操作
修复代码:
// XXX.h修改 #define EOL "\r\n" #define EOL_SIZE 2 // 补充长度定义 // recv_line函数修改 int recv_line(int sockfd, unsigned char *dest_buffer){ printf("int recv_line()\n"); unsigned char *ptr; int eol_match = 0; ptr = dest_buffer; printf("assigning to ptr done\n"); while(recv(sockfd, ptr, 1, 0) == 1){ printf("."); if(*ptr == EOL[eol_match]){ eol_match++; if(eol_match == EOL_SIZE){ *(ptr+1-EOL_SIZE) = '\0'; return strlen(dest_buffer); } } else { eol_match = 0; // 匹配失败重置计数器,把双等号改为单等号 } ptr++; } return 0; }
3. 请求方法判断逻辑错误
strcmp函数返回0才代表两个字符串相等,当前if(strcmp(request, "GET "))的逻辑完全相反,只有不是GET请求时才会进入分支。
修复代码:
if(strcmp(request, "GET ") == 0){ // 补充相等判断 ptr = request+4; printf("is a get request\n"); } if(strcmp(request, "HEAD ") == 0){ // 补充相等判断 ptr = request+5; printf("is a head request\n"); }
4. 200响应存在多处协议错误
- 发送Server头时,长度错误使用了第一个响应头的长度,导致Server头发送不全
- 响应头和响应体之间缺少HTTP协议要求的空行(
\r\n\r\n),浏览器无法区分响应头和响应体 - 没有发送
Content-Length头,浏览器不知道响应体长度,会一直等待数据
修复代码:
else{ printf("200 OK\n"); unsigned char temp_buffer[] = "HTTP/1.0 200 OK\r\n"; send(sockfd, temp_buffer, strlen(temp_buffer), 0); unsigned char temp2_buffer[] = "Server: Tiny webserver\r\n"; send(sockfd, temp2_buffer, strlen(temp2_buffer), 0); // 修正长度为temp2_buffer的长度 // 新增Content-Length头和响应头结束空行 int file_len = get_file_size(fd); char cl_header[64]; snprintf(cl_header, sizeof(cl_header), "Content-Length: %d\r\n\r\n", file_len); send(sockfd, cl_header, strlen(cl_header), 0); printf("done sending basic info\n"); if(strcmp(request, "GET ") == 0){ printf("ptr is request+4\n"); if((ptr = (unsigned char *)malloc(file_len)) == NULL){ printf("Error: while allocatin memory of heap\n"); exit(0); } printf("passed get_file_size() and malloc() succesfully\n"); read(fd, ptr, file_len); send(sockfd, ptr, file_len, 0); printf("file sent\n"); free(ptr); } close(fd); }
5. 请求处理完未关闭客户端socket
handle_connection处理完所有逻辑后没有关闭客户端socket连接,浏览器会一直保持连接等待后续数据,导致页面无限加载。
修复方法:在handle_connection函数末尾添加关闭socket的代码:
void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr){ // 原有所有逻辑不变 close(sockfd); // 新增这行,处理完请求主动关闭连接 }
修复以上所有问题后,服务端即可正常返回响应,浏览器也能正常加载页面。
内容的提问来源于stack exchange,提问作者user14622805
相关产品推荐
相关产品推荐

