-1

我有两个过程:daemonclient. 两者都是不同的插座。./daemon最初我通过然后执行守护程序套接字 ./client

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

我刚刚编辑了原始代码。

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

但是当我发送请求./client时它没有响应。并说error connecting socket 111

daemon正在侦听1104和客户端发送请求相同。当我执行./daemon它说 Error binding to socket, make sure nothing else is listening on this port 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
}
4

2 回答 2

2

您在打电话listen之前先打电话bind- 您应该bind先打电话。

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

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);
于 2013-09-23T14:42:49.963 回答
0

解决方案非常简单:无需大量编码,只需&完成所有工作。

代替执行./daemon使用./daemon &。这将使守护进程继续侦听

于 2013-09-26T06:14:45.857 回答