首页 > 解决方案 > 尝试在 C 中创建基本套接字连接并在 accept() 上运行到无限循环

问题描述

我有一个任务,我需要创建一个简单的 HTTP 服务器来处理 GET 请求并从包含此代码的可执行文件的目录中的目录返回信息。我试图在解决 HTTP 请求之前在套接字之间建立连接。但是,当我尝试使用它将客户端连接到服务器时,accept()它会触发一个无限循环,其中 gdb 显示此消息:

../sysdeps/unix/sysv/linux/accept.c:26
26 ../sysdeps/unix/sysv/linux/accept.c:没有这样的文件或目录。
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>

int main(int argc, char* argv[]){
    if(argc>1){
        perror("Error there should be no command line arguments");
        exit(0);
    }
    int sockfd = 0;
    int clientfd = 0;
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0))<0){ //create socket and check for error
        perror("Error in socket creation");
        exit(0);
    }
//create sockaddr object to hold info about the socket
    struct sockaddr_in server, client;
    server.sin_family = AF_INET;
    server.sin_port = 0;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    socklen_t sockSize = sizeof(server);
//Bind the socket to a physical address exit if there is an error
    if((bind(sockfd, (struct sockaddr*)&server, sockSize))<0){
        perror("Error binding socket");
        exit(0);
    }
//Check server details
    printf("-------Server Details----------\n");
    printf("Port number %d | IP ADDRESS %d\n", ntohs(server.sin_port), (getsockname(sockfd, (struct sockaddr*)&server, &sockSize)));
    if((getsockname(sockfd, (struct sockaddr*)&server, &sockSize)) <0){
        perror("There is an error in the sock");
        exit(0);
    }
    if(listen(sockfd, 5) <0){
        perror("Error switching socket to listen");
        exit(0);
    }
    while((clientfd = accept(sockfd, (struct sockaddr*)&client, (socklen_t*)&sockSize))){
        printf("Socket is awaiting connections");
    }
// figure out how to setup client to accept and submit HTTP requests
    close(sockfd);
    return 0;
}

标签: csocketshttp

解决方案


accept()失败时返回 -1。Anif会将任何非零值视为true条件。

您的循环应该更像以下内容:

// setup listening socket...

printf("Socket is awaiting connections");

while (1) {
    sockSize = sizeof(client); // <-- add this

    if ((clientfd = accept(sockfd, (struct sockaddr*)&client, (socklen_t*)&sockSize)) < 0) {
        if (errno != EINTR) {
            // fatal error, bail out...
            break;
        }
        continue; // retry...
    }

    printf("Client connected");

    // use clientfd to read HTTP request and send HTTP response...

    close(clientfd);
}

推荐阅读