c++ - 守护进程套接字在后台监听请求

标签 c++ linux sockets

我有两个进程:守护进程客户端。两者是不同的套接字。最初我通过执行守护进程套接字 ./daemon 然后 ./client.

但我希望守护进程应该始终在后台监听来自客户端的请求。因此,我尝试使用 fork() 创建这样一个过程。

我刚刚编辑了原始代码。

现在我可以编译守护程序文件并创建可执行守护程序

但是当我发送请求./client时它没有响应。并显示连接套接字 111 时出错

守护进程正在监听1104,并且客户端在同一端口上发送请求。 当我执行 ./daemon 时,它说 绑定(bind)到套接字时出错,请确保没有其他东西正在监听此端口 22n

意味着它在后台运行但不响应请求。 代码:

#include <fcntl.h>
#include <string.h>
#include <algorithm>

#include "dictionary_exclude.h"
#pragma GCC diagnostic ignored "-Wwrite-strings"

#define CHECK_THROW(condition, code) if(condition) throw code
void *SocketHandler(void *);
int OpenSocket();
int main(int argv, char **argc)
{
    int host_port = 1104;
    char buf[20];
    int k;
    struct sockaddr_in my_addr;
    int hsock;
    int *p_int;
    int err;
    socklen_t addr_size = 0;
    int *csock;
    sockaddr_in sadr;
    pthread_t thread_id = 0;

    try {
    pid_t pid = fork();
    CHECK_THROW(pid < 0, -5);
    if (pid == 0) {
        mode_t umask(mode_t mask);
        pid_t childid = setsid();

        hsock = OpenSocket();   // Function call for hsock
        CHECK_THROW(listen(hsock, 10) == -1, -4);
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(host_port);

        memset(&(my_addr.sin_zero), 0, 8);
        my_addr.sin_addr.s_addr = INADDR_ANY;

        if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
        fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
        exit(EXIT_SUCCESS);
        }
        if (listen(hsock, 10) == -1) {
        fprintf(stderr, "Error listening %dn", errno);
        exit(EXIT_SUCCESS);
        }
        //Now lets do the server stuff

        addr_size = sizeof(sockaddr_in);

        while (true) {
        printf("waiting for a connectionnn");
        csock = (int *) malloc(sizeof(int));
        if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
            printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
            pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
            pthread_detach(thread_id);
        } else {
            fprintf(stderr, "Error accepting %dn", errno);
        }
        }           //while end
    }           //if (pid) end
    }               //try

    catch(int ierror) {
    switch (ierror) {
    case -4:
        fprintf(stderr, "Error listening %dn", errno);
        break;
    case -7:
        fprintf(stderr, "Error accepting %dn", errno);
        break;
    }
    }

}

int OpenSocket()
{
    // Create your socket and return the socket handle from this function 
    int hsock;
    int *p_int;
    hsock = socket(AF_INET, SOCK_STREAM, 0);
    if (hsock == -1) {
    printf("Error initializing socket %dn", errno);
    exit(EXIT_SUCCESS);
    }

    p_int = (int *) malloc(sizeof(int));
    *p_int = 1;

    if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
    printf("Error setting options %dn", errno);
    free(p_int);
    exit(EXIT_SUCCESS);
    }
    free(p_int);
    return hsock;
}


void *SocketHandler(void *lp)
{

    //some procesing
}

有人可以说上面的代码有什么问题吗?

原始代码是:

int main(int argv, char **argc)
{
    int host_port = 1104;
    char buf[20];
    int k;
    struct sockaddr_in my_addr;
    int hsock;
    int *p_int;
    int err;
    socklen_t addr_size = 0;
    int *csock;
    sockaddr_in sadr;
    pthread_t thread_id = 0;

    try {
    pid_t pid = fork();
    CHECK_THROW(pid < 0, -5);
    if (pid == 0) {
        mode_t umask(mode_t mask);
        pid_t childid = setsid();

        hsock = OpenSocket();   // Function call for hsock
        CHECK_THROW(listen(hsock, 10) == -1, -4);
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(host_port);

        memset(&(my_addr.sin_zero), 0, 8);
        my_addr.sin_addr.s_addr = INADDR_ANY;

        if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) {
        fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno);
        exit(EXIT_SUCCESS);
        }
        if (listen(hsock, 10) == -1) {
        fprintf(stderr, "Error listening %dn", errno);
        exit(EXIT_SUCCESS);
        }
        //Now lets do the server stuff

        addr_size = sizeof(sockaddr_in);

        while (true) {
        printf("waiting for a connectionnn");
        csock = (int *) malloc(sizeof(int));
        if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) {
            printf("---------------------nReceived connection from %sn", inet_ntoa(sadr.sin_addr));
            pthread_create(&thread_id, 0, &SocketHandler, (void *) csock);
            pthread_detach(thread_id);
        } else {
            fprintf(stderr, "Error accepting %dn", errno);
        }
        }           //while end
    }           //if (pid) end
    }               //try

    catch(int ierror) {
    switch (ierror) {
    case -4:
        fprintf(stderr, "Error listening %dn", errno);
        break;
    case -7:
        fprintf(stderr, "Error accepting %dn", errno);
        break;
    }
    }

}

int OpenSocket()
{
    // Create your socket and return the socket handle from this function 
    int hsock;
    int *p_int;
    hsock = socket(AF_INET, SOCK_STREAM, 0);
    if (hsock == -1) {
    printf("Error initializing socket %dn", errno);
    exit(EXIT_SUCCESS);
    }

    p_int = (int *) malloc(sizeof(int));
    *p_int = 1;

    if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) {
    printf("Error setting options %dn", errno);
    free(p_int);
    exit(EXIT_SUCCESS);
    }
    free(p_int);
    return hsock;
}

void *SocketHandler(void *lp)
{

    //some procesing
}

最佳答案

您在调用 bind 之前调用 listen - 您应该先调用 bind

实际上,您在调用 bind 之前和之后调用了 listen 两次。删除第一个调用。

hsock = OpenSocket();
// remove this line:
CHECK_THROW(listen(hsock, 10) == -1, -4); 
my_addr.sin_family = AF_INET;

另一项改进:使用 strerrorperror 生成错误消息,以便您获得用户友好的消息。例如:

perror("Error binding to socket");
exit(EXIT_SUCCESS);

关于c++ - 守护进程套接字在后台监听请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18961663/

相关文章:

c++ - 如何在 Linux 中查询 Vsync 阶段

c# - 在FTP服务器(PASV)上使用RETR时如何确定文件结尾

python - 重复的 transient 套接字连接 - 内存泄漏风险?

c++ - SACSegmentation检测奇平面模型

python - 协程中的异步运行时错误 : no running event loop

c++ - 截断并转换为 ceiled double 的 int

swift - 后端错误 : invalid llvm. linker.options 在 Ubuntu 18.10 上构建 SourceKit-LSP

node.js - nodejs socket.io - 连接到服务器但发出不执行任何操作

c++ - 在 C++ 中以编程方式在编译时创建静态数组

c++ - 如何调整无序的 STL 容器以仅存储键值对的值?