5

我正在为最多 1000 个客户端编写套接字服务器,服务器是关于我的游戏的,我使用非阻塞套接字和大约 10 个线程同时从不同的套接字接收数据(第一个线程从 0-100 接收,第二个从 101-200等等..)

但是如果线程 1 想向所有 1000 个客户端发送数据,而线程 2 也想同时向所有 1000 个客户端发送数据,那安全吗?数据是否有可能在另一端(客户端)被弄乱?

如果是,我想唯一可能发生的问题是有时客户端会收到 2 个或 10 个数据包作为 1 个数据包,对吗?如果是的话,有什么解决办法吗:(

4

4 回答 4

2

处理许多套接字的通常模式是使用 、 或更好的或(取决于平台)充当套接字事件调度程序的 I/O 事件的select(2)专用poll(2)线程kqueue(2)轮询epoll(4)。套接字通常以非阻塞模式处理。然后,可能会有线程池对事件做出反应,要么直接进行读写,要么通过较低级别的缓冲区/队列进行读写。

各种技术都适用于这里——从队列到事件订阅白板。在 I/O 级别多路复用接受/读取/写入/EOF 以及在应用程序级别进行事件仲裁会变得很棘手。几个库喜欢libeventboost::asio帮助构建较低级别(ACE 库也在这个领域,但我不喜欢向任何人推荐它)。您必须自己提出应用程序级协议和状态机(再次boost::statechart可能会有所帮助)。

一些很好的链接可以更好地了解您所面临的问题(这可能是他们在 SO 上被提及的第 100 万次):

很抱歉没有提供具体的解决方案,但这是一个非常广泛的设计问题,大多数决策很大程度上取决于上下文(虽然很有趣)。希望这个对你有帮助。

于 2010-07-16T13:12:54.457 回答
1

由于您使用不同的套接字发送数据,因此一定没有任何问题。相反,当这些不同的线程访问相同的数据时,您必须确保数据完整性。

于 2010-07-13T08:46:37.343 回答
0

send() 在大多数实现中不是原子的,因此从多个线程发送到 1000 个不同的套接字可能会导致到达客户端的混合消息以及各种奇怪的事情。 (我什么都不知道,请参阅 Nicolai 和 Robert 的评论,我的其余评论仍然有效(就解决您的问题而言))

我要做的是使用线程进行发送,就像您使用它们进行接收一样。一个线程来管理发送到一个(或多个)套接字,以确保您不会同时从多个线程写入一个套接字。

还可以在这里寻找一些额外的讨论和更有趣的链接。如果您使用的是 Windows,winsock 程序员常见问题解答是非常宝贵的资源,您的问题请参见此处

于 2010-07-13T09:39:36.500 回答
0

您使用的是 UDP 还是 TCP 套接字?

如果是 UDP,则每次写入都应封装在单独的数据包中,并应原封不动地传送到另一端。顺序可以交换(因为它可以用于任何 UDP 数据包),但它们应该是完整的。

如果是 TCP,则传输层没有数据包的概念,并且一侧的任何 10 次写入都可能在一次读取中捆绑在另一侧。TCP 写入也可能只接受缓冲区的一部分,因此即使 send() 函数是原子的,您的写入也不一定。在这种情况下,您需要同步它。

于 2010-07-14T10:12:07.527 回答