使用信号量处理C语言中的套接字

时间:2014-11-24 15:08:41

标签: c sockets semaphore

我有以下代码:

SOCKET sock = open_socket(szListenHost, iListenPort);

if (sock > 0) {
    SOCKET client;
    struct sockaddr_in peeraddr;
    T_socklen len = sizeof (struct sockaddr_in);

    char buf[1024];

    sin.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    sin.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    sin.hStdOutput =  GetStdHandle(STD_OUTPUT_HANDLE);
    sin.hStdError = GetStdHandle(STD_ERROR_HANDLE);
    sin.wShowWindow = SW_HIDE;
    dwCreationFlags = CREATE_NO_WINDOW;

    CreateProcess(NULL, buf, NULL, NULL, FALSE, dwCreationFlags, NULL, NULL, &sin, &pin);

    memset(&peeraddr, 0, sizeof (struct sockaddr_in));
    client = accept(sock, (sockaddr*)&peeraddr, &len);

    if (client > 0) {
        rv = message_loop(client);
    }
    closesocket(sock);
}

正如您所看到的,这是为了审讯原因而打开TCP套接字。

情况如下:我的客户端应用程序(打开这些套接字)可能需要同时打开不同的TCP套接字,这可能会导致问题。

为了避免这些问题,我想问一下套接字是否已经打开。如果是,则等待再次释放套接字,然后再次尝试打开套接字。

我已经知道信号量可以用于此目的,但我不知道如何做到这一点。

任何人都可以帮助我吗? 感谢

首先,我要感谢John Bollinger的快速回复。不幸的是他们似乎是误解:我不是想找到一种方法同时打开一个插槽不同的时间,但我正在寻找一种方法,当一个插座可用时被注意到。事实上,我想做以下事情:而不是:

SOCKET sock = open_socket(szListenHost, iListenPort);

我能做到这一点(非常基本):

while (open_socket(szListenHost, iListenPort)) {sleep (1 second;)}

然而,这意味着我需要不断轮询套接字,从而产生相当大的开销。我听说信号量可以解决这个问题,例如:

SOCKET sock = handle_semaphore(open_socket(szListenHost, iListenPort));

和" handle_semaphore"然后是一个自动等待套接字被释放的系统,这样我的客户端进程就可以立即打开套接字,而不会被推到后面。正如你所看到的,这完全是关于谣言,但我不知道如何实现这一点。有没有人知道信号量是否可用于此意图,如果可能的话,请给我一些指导如何做到这一点?

由于

2 个答案:

答案 0 :(得分:1)

一旦打开,即使关闭了套接字也无法重新打开。但是,您可以创建一个类似的新套接字。无论哪种方式,都很难可靠地确定先前打开的插座是否已关闭,除非关闭它。

在任何情况下,通常的范例都不需要您提出的那种协调机制。通常,一个进程的一个线程将打开套接字并负责接受它上的连接。如果希望程序能够一次处理多个连接,那么每次该线程接受新连接时,它都会指定该连接由另一个线程或进程处理 - 通常但不一定是新创建的。

通常不需要或不希望打开新套接字以在同一地址和端口接收其他连接。通常您只需使用相同的套接字,而无需关心已通过该套接字建立的任何连接的状态。或许,您可以使用信号量来协调从同一个套接字接收连接的同一进程的多个线程,但如果我是你,我会避免使用它。

答案 1 :(得分:0)

同时情况发生了变化,我现在已经能够将信号量添加到我的套接字相关应用程序中。通常这有效,但有时应用程序会挂起。

经过一些调试后,我了解到应用程序在我按照C命令启动时挂起:

printf("Will it be accepted?\n");

fflush(stdout);

memset(&peeraddr, 0, sizeof (struct sockaddr_in));

client = accept(sock, (sockaddr*)&peeraddr, &len);

printf("It is accepted, the client is %d.\n",client);

=>我可以在我的调试日志中看到“它会被接受吗?”,但我没有看到“它已被接受,......”。

我承认我在测试时非常暴力(有时我会在不给应用程序关闭套接字的情况下停止调试会话,...),但你可以想象客户的行为方式相同,应用程序需要足够的鲁棒性。

有人知道如何避免“接受”命令进入这样一个无限循环吗?

由于