You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 23:06:05