0

我对套接字编程完全陌生,我想用 C 编写一个组合的 TCP/UDP-Server 套接字,但我不知道如何将这两者结合起来。

所以目前,我确实知道 TCP 和 UDP 服务器/客户端是如何工作的,并且我已经为 TCP 和 UDP 编写了客户端。我也知道我必须以某种方式使用 select() 函数,但我不知道该怎么做。

我必须读取两个数字,它们使用 TCP 或 UDP 客户端发送到 TCP/UDP 服务器,然后用这些数字进行一些计算,然后在服务器上打印结果。

有谁知道该教程或示例代码,或者可以帮助我吗?

或者至少是对 select() 函数的一个很好的解释。

4

4 回答 4

4

基本上,使用事件循环。它是这样工作的:

  1. 我现在有什么需要做的吗?如果是这样,那就去做吧。

  2. 计算我下一次需要做某事的时间。

  3. 调用select指定我愿意在读取集中读取的所有套接字以及我试图在写入集中写入的所有套接字。

  4. 如果我们发现任何可以读取的套接字,请从中读取。

  5. 如果我们发现任何已准备好写入的套接字,请尝试写入它们。如果我们写了我们需要写的所有东西,请将它们从写集中删除。

  6. 转到步骤 1。

通常,要写入套接字,请遵循以下逻辑:

  1. 我是否已经尝试写入此套接字?如果是这样,只需将其添加到队列中,我们就完成了。

  2. 尝试将数据写入套接字。如果我们全部发送,我们就完成了。

  3. 将剩余的保存在队列中并将这个套接字添加到我们的写入集中。

要记住三件事:

  1. 您必须将所有套接字设置为非阻塞。

  2. 确保在将文件描述符集传递给之前复制它们,select因为select会修改它们。

  3. 对于 TCP 连接,您可能需要自己的写入队列。

于 2013-04-21T23:09:35.580 回答
0

1)简单编写一个tcp/udp服务器代码,收到消息后打印出来。

2) 将打印代码替换为 process_message() 函数。

然后你已经成功地将 TCP 和 UDP 服务器结合到相同的过程中。

小心你的处理程序,它应该能够应对并行执行。

于 2013-04-27T06:02:01.123 回答
0

这个想法是在你的服务器内部混合一个 TCP 部分和一个 UDP 部分。

然后多路复用输入。您可以使用旧的select(2)多路复用调用,但它有局限性(google for C10K problem)。最好使用poll(2) 多路复用调用。

您可能想要使用一些事件循环库,例如libev(它使用selectpoll或一些更高级的机制,例如epoll)。顺便说一句,图形工具包(例如 GTK 或 Qt)也提供了它们自己的偶数循环机制。

阅读一些不错的 Linux 编程书籍,例如Advanced Linux Programming 书籍(可在线获得),其中有关于多路复用系统调用和事件循环的好章节。这些太复杂了,无法在几分钟内在这样的答案中很好地解释。书籍更好地解释了它们。

于 2013-04-21T23:10:52.157 回答
0

你可以试试这个stream_route_handler,它是 c/c++ 应用程序,你可以在你的单个 c/c++ 应用程序中添加 tcp/udp 处理程序。这一直被用于交通繁忙的路线,以及测井服务的目的。

使用示例

void read_data(srh_request_t *req);
void read_data(srh_request_t *req) {
  char *a = "CAUSE ERROR FREE INVALID";

  if (strncmp( (char*)req->in_buff->start, "ERROR", 5) == 0) {
    free(a);
  }
  // printf("%d,  %.*s\n", i++, (int) (req->in_buff->end - req->in_buff->start), req->in_buff->start);
  srh_write_output_buffer_l(req, req->in_buff->start, (req->in_buff->end - req->in_buff->start));
  // printf("%d,  %.*s\n", i++, (int) (req->out_buff->end - req->out_buff->start),   req->out_buff->start);
} 

int main(void) {

  srh_instance_t * instance = srh_create_routing_instance(24, NULL, NULL);
  srh_add_udp_fd(instance, 12345, read_data, 1024);
  srh_add_tcp_fd(instance, 3232, read_data, 64);

  srh_start(instance);

  return 0;
}

如果您使用的是 C++ 程序,您可能会喜欢这个示例代码。 使用 spdlog 的流路由

于 2018-07-08T02:17:51.090 回答