【问题标题】:listen() does not block processlisten() 不会阻塞进程
【发布时间】:2014-09-10 14:21:08
【问题描述】:

编辑:没关系!我花了几个小时试图得到错误...我使用的是 connect() 而不是 accept()...真丢脸。

编辑 2: 我想说明此代码可能没有意义,这是因为我目前正在研究该主题,而您在此页面中找到的内容是我的第一个测试。谢谢!

这是我正在编写的一个非常简单的服务器的代码...我不明白为什么 listen() 函数不会阻止直接进入 connect() 的过程,但它没有给我错误22 - Invalid argument。有什么问题?谢谢。

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>

#define BUFMAXSIZE 1024
#define MAXLISTEN 10
#define SOCKERROR -1

int main(int argc, char *argv[]) {

    int localPort;

    int sockfd, sockbind, socklist, sockaccept;
    struct sockaddr_in local, remote;
    int remoteSize;

    char readMsg[BUFMAXSIZE];
    int totalReadLen, singleLoopRead;

    char answer[BUFMAXSIZE];
    int totalSentLen, singleLoopSent, answerLen;

    // Checking parameters
    if(argc < 2) {
        printf("Usage: server LOCAL_PORT_NUMBER\n");
        exit(1);
    }
    else {
        localPort = atoi(argv[1]);
    }

    // Creating socket
    printf("Creating socket...\n");
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == SOCKERROR) {
        printf("Error: could not open socket.\n");
        exit(1);
    }
    printf("Socket created.\n");

    // Setting local information
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_port = htons(localPort);

    // Binding
    printf("Setting local information...\n");
    sockbind = bind(sockfd, (struct sockaddr*) &local, sizeof(local));
    if(sockbind == SOCKERROR) {
        printf("Error: could not bind socket.\n");
        exit(1);
    }
    printf("Socket binded.\n");

    // Listening
    printf("Listening on %d:%d...\n", ntohl(local.sin_addr.s_addr), ntohs(local.sin_port));
    socklist = listen(sockfd, MAXLISTEN);
    if(socklist == SOCKERROR) {
        printf("Error: could not listen.\n");
        exit(1);
    }

    // Accepting connection
    printf("Accepting connection...\n");
    memset(&remote, 0, sizeof(remote));
    remoteSize = sizeof(remote);
    sockaccept = connect(sockfd, (struct sockaddr*) &remote, &remoteSize);
    if(sockaccept == SOCKERROR) {
        printf("Error: could not accept connection.\n");
        exit(1);
    }
    printf("Connection accepted.\n");

    // Reading data
    printf("Reading data...\n");
    totalReadLen = 0;
    singleLoopRead = 0;
    while(BUFMAXSIZE > totalReadLen && (singleLoopRead = read(sockaccept, &(readMsg[totalReadLen]), BUFMAXSIZE - totalReadLen)) > 0) {
        totalReadLen += singleLoopRead;
        if(singleLoopRead < 0) {
            printf("Error: could not read data.\n");
            exit(1);
        }
        else {
            printf("Data read: %d.\n", singleLoopRead);
        }
    }
    printf("Read message: %s.", readMsg);

    // Sending answer
    printf("Sending answer...");
    totalSentLen = 0;
    singleLoopSent = 0;
    strncpy(answer, "Data have been received.", BUFMAXSIZE - 1);
    answerLen = strlen(answer);
    fflush(stdout);
    while((singleLoopSent = write(sockaccept, &(answer[totalSentLen]), answerLen - totalSentLen)) > 0) {
        totalSentLen += singleLoopSent;
        if(singleLoopSent < 0) {
            printf("Error: could not send answer.\n");
            fflush(stdout);
            exit(1);
        }
        else {
            printf("Total data sent: %d bytes.\n", totalSentLen);
        }
    }
    fflush(stdout);
    printf("Answer correctly sent.\n");

    // Closing sockets
    printf("Closing connection...\n");
    close(sockaccept);
    close(sockfd);
    printf("Connection closed.\n");

    return 0;
}

【问题讨论】:

    标签: sockets tcp connection tcpserver listen


    【解决方案1】:

    我不明白为什么listen()函数不阻塞进程

    因为它不是阻塞函数。它将端口置于 LISTEN 状态。 accept() 是阻塞函数,接下来应该调用它。

    直接进入 connect() 失败,给我错误 22 - Invalid argument。

    因为socket处于LISTEN状态,因为你调用了listen()。您无法连接侦听套接字。你应该调用accept()

    有什么问题?

    问题是你的代码没有意义。

    【讨论】:

    • 这可能没有意义,我正在研究这个并尝试做事情。无论如何,我现在解决了我的问题,感谢您的帮助!
    • @Crecker 没有人攻击过你。这里零个人评论。我建议你停止射击信使。
    猜你喜欢
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 2021-06-10
    • 2017-10-03
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 2017-01-22
    相关资源
    最近更新 更多