0

我有两个线程,一个在accept() 中被阻止用于新连接,另一个与其他进程通信。当我的应用程序要关闭时,我需要从 accept() 唤醒第一个线程。我试图阅读 accept() 的手册页,但没有发现某些内容已满。我的问题是我应该从第二个线程向第一个线程发送哪个信号,这样它就不会被接受并且不会被杀死?

谢谢。

4

2 回答 2

2

您可以将 aselect与超时一起使用,例如,accept如果没有任何反应,您的线程执行每 1 或 2 秒唤醒一次并检查是否关闭。您可以查看此页面以了解情况。

于 2013-07-17T13:01:47.733 回答
0

不使用“选择”

示例代码在 Windows 上运行良好。当 SIGINT 引发时,它显示“退出”。您可以编辑适合 Linux 的代码。几乎每个套接字函数都是相同的,除了你应该使用“close”而不是“closesocket”,你应该删除前两行代码,它是关于启动 winsock 并为 Linux 添加必要的头文件。

#include <stdio.h>
#include <winsock.h>
#include <signal.h>
#include <thread>

#pragma comment(lib,"wsock32.lib")

jmp_buf EXIT_POINT;

int sock,sockl=sizeof(struct sockaddr);
struct sockaddr_in xx,client;
int AcceptConnections = 1;

void _catchsignal(int signal)
{
    closesocket(sock);
}

void thread_accept()
{
    accept(sock,(struct sockaddr*)&client,&sockl);
}

void thread_sleep()
{
    Sleep(1000);
    raise(SIGINT);
}

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD( 2, 2 ),&wsaData);
    signal(SIGINT,_catchsignal);
    xx.sin_addr.s_addr = INADDR_ANY;
    xx.sin_family = AF_INET;
    xx.sin_port = htons(9090);
    sock = socket(AF_INET,SOCK_STREAM,0);
    bind(sock,(struct sockaddr*)&xx,sizeof(struct sockaddr));
    listen(sock,20);

    std::thread th_accept(thread_accept);
    std::thread th_sleep(thread_sleep);

    th_accept.join();
    th_sleep.join();

    printf("Exit");
    return 0;
}

首先,您可以在不阻塞线程的情况下将“select”函数用于接受函数。您可以在msdnbeej中了解有关 select 的更多信息,我的建议是查看最后一个,您可以在套接字编程上使用 MSDN 资源,因为 Windows 和大多数操作系统都使用几乎相同的 BSD 套接字。在接受连接而不阻塞它们后,您只需定义一个可以停止循环的全局变量。

对不起我的英语,这是一个示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

#define DEFAULT_PORT 9090
#define QUEUE_LIMIT 20

int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD( 2, 2 ),&wsaData);

    int ServerStream,SocketQueueMax=0,i,j,TMP_ClientStream;
    int ClientAddrSize = sizeof(struct sockaddr),RecvBufferLength;
    fd_set SocketQueue,SocketReadQueue,SocketWriteQueue;
    struct sockaddr_in ServerAddr,TMP_ClientAddr;
    struct timeval SocketTimeout;
    char RecvBuffer[255];
    const char *HelloMsg = "Connected.";

    SocketTimeout.tv_sec = 1;


    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(DEFAULT_PORT);

    ServerStream = socket(AF_INET,SOCK_STREAM,0);
    bind(ServerStream,(struct sockaddr*)&ServerAddr,sizeof(struct sockaddr));
    listen(ServerStream,QUEUE_LIMIT);

    FD_ZERO(&SocketQueue);
    FD_ZERO(&SocketReadQueue);
    FD_ZERO(&SocketWriteQueue);

    FD_SET(ServerStream,&SocketQueue);

    SocketQueueMax = ServerStream;
    bool AcceptConnections = 1;
    while(AcceptConnections)
    {
        SocketReadQueue = SocketQueue;
        SocketWriteQueue = SocketQueue;

        select(SocketQueueMax + 1,&SocketReadQueue,&SocketWriteQueue,NULL,&SocketTimeout);

        for(i=0;i < SocketQueueMax + 1;i++)
        {
            if(FD_ISSET(i,&SocketReadQueue))
            {
                if(i == ServerStream)
                {
                    TMP_ClientStream = accept(ServerStream,(struct sockaddr*)&TMP_ClientAddr,&ClientAddrSize);
                    send(TMP_ClientStream,HelloMsg,strlen(HelloMsg),0);

                    FD_SET(TMP_ClientStream,&SocketQueue);
                    if(TMP_ClientStream > SocketQueueMax)
                    {
                        SocketQueueMax = TMP_ClientStream;
                    }
                    continue;
                }

                while((RecvBufferLength = recv(i,RecvBuffer,254,0)) > 0)
                {
                    RecvBuffer[RecvBufferLength] = '\0';
                    for(j=0;j<SocketQueueMax + 1;j++)
                    {
                        if(j == i || j == ServerStream || !FD_ISSET(j,&SocketQueue))
                        {
                            continue;
                        }
                        send(j,RecvBuffer,RecvBufferLength + 1,0);
                    }
                    printf("%s",RecvBuffer);
                    if(RecvBufferLength < 254)
                    {
                        break;
                    }
                }

            }
        }
    }

    return EXIT_SUCCESS;
}
于 2013-07-17T13:04:58.243 回答