【问题标题】:Binding/listening on multiple ports, is pthreads the correct way?在多个端口上绑定/侦听,pthreads 是正确的方法吗?
【发布时间】:2013-10-03 06:36:08
【问题描述】:

我注意到 netcat 不允许您仅在单个端口上侦听端口范围。我用 C 语言编写了一个基本的类似 netcat 的程序,带有一个客户端和一个服务器功能。我现在正在研究监听多个端口的最佳方式。

我的目标是这样的用法:程序 localhost 200 300(其中 200 是开始,300 是结束端口)。

pthreads 是最好的方法吗?在每个线程上绑定/侦听,然后在建立连接时将它们加入备份?

 iret1 = pthread_create( &thread1, NULL, bind_function, (void*) somename);
 pthread_join( thread1, NULL);

线程确实是一个新领域,我不确定是否有更简单的方法,或者您将如何进一步使用 iret1(返回值)。任何人都可以添加这个吗?

Dolda2000 的注意事项:

我在epoll上遇到的一个使用例子:

for (j = 1; j < argc; j++) {
        fd = open(argv[j], O_RDONLY);
        if (fd == -1)
            errExit("open");
        printf("Opened \"%s\" on fd %d\n", argv[j], fd);

        ev.events = EPOLLIN;            /* Only interested in input events */
        ev.data.fd = fd;
        if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1)
            errExit("epoll_ctl");
    }

我的绑定码:

if (bind(sockfd, (struct sockaddr *) &server_addr, server_len) < 0)
        error("ERROR");
        listen(sockfd,5);

newsockfd = accept(sockfd, (struct sockaddr *) &client_addr, &clilen);

【问题讨论】:

  • 如果您只想听,请参阅@Dolda2000 的回答。有一些事情会激发线程超过选择,但只是监听端口不是其中之一。
  • IIRC 每个线程默认有大约 8mb 的开销,对于小程序 (

标签: c linux


【解决方案1】:

当然,改用select/poll/epoll 会更容易且占用资源更少?

我不确定你到底遇到了什么问题,所以这里有一些使用 poll 的示例代码:

int listentoall(int firstport, int lastport)
{
    int i, nsk;
    int nfd = lastport - firstport + 1;
    struct pollfd fds[nfd];
    struct sockaddr_in name;

    memset(&name, 0, sizeof(name));
    name.sin_family = AF_INET;
    for(i = 0; i < nfd; i++) {
        fds[i].fd = socket(PF_INET, SOCK_STREAM, 0);
        name.sin_port = htons(firstport + i);
        bind(fds[i].fd, (struct sockaddr *)&name, sizeof(name));
        listen(fds[i].fd, 5);
        fds[i].events = POLLIN;
    }

    while(1) {
        poll(fds, nfd, -1);
        for(i = 0; i < nfd; i++) {
            if(fds[i].revents & POLLIN) {
                nsk = accept(fds[i].fd, NULL, NULL);
                for(i = 0; i <nfd; i++)
                    close(fds[i].fd);
                return(nsk);
            }
        }
    }
}

请注意,我现在只是写了这段代码,没有编译它,所以很可能有错别字之类的,而且它显然没有错误检查,但也许它足以解释一般结构?

【讨论】:

  • 对不起,您将如何遍历范围内的端口绑定并将它们注册为 epoll?我是否也认为 select 不足以满足 1-65k 的完整端口范围?一旦在任何端口上收到连接,我希望它们全部打开并停止监听,除了连接的端口
  • 您对迭代所有套接字有什么疑惑?是你不懂的API,还是别的什么?但是,您认为select 并没有走那么远是对的。但pollepoll 都可以。
  • 感谢您的回答。我用示例 api 用法更新了我的帖子,并在下面更新了我如何绑定/侦听/接受一个端口。我所说的迭代的意思是我可以做一个 for 循环来绑定/监听端口范围,但是我不确定 epoll 与 accept() 的交互。
【解决方案2】:

执行此操作的典型方法是在 linux 上使用 select 或 poll 或 epoll。这里有几个很好的话题讨论:

blocking select() from multiple sockets

selecting among multiple sockets that are ready to be read from

【讨论】:

    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 2013-09-24
    相关资源
    最近更新 更多