【问题标题】:Client to client messaging in socket programming套接字编程中的客户端到客户端消息传递
【发布时间】:2015-02-16 08:24:33
【问题描述】:

我正在开发一个基于 C++ 中 WinSock 的服务器-客户端应用程序的项目。我已经完成了服务器和客户端之间通信所需的一切,我能够在它们之间发送和接收消息。

现在我需要知道如何完成客户端到客户端的消息传递部分以及必须如何完成工作。我只知道,比如客户端A和客户端B需要相互通信,客户端A必须将消息发送到服务器,服务器接收到消息并将其发送给客户端B。

如果这是正确的方法,请帮助我了解服务器应该如何知道接收者的任何信息(在这种情况下是客户端 B)?

如果我没有解释清楚我的问题,请告诉我。

感谢任何帮助。

【问题讨论】:

  • 我这样做的方式是,每次客户端连接到服务器时,我都会给该客户端一个唯一的 ID。每当另一个客户端想要发送消息时,它都会发送 Receiver 的 UniqueID 和消息。服务器将该消息发送到带有该消息的目标 ID 的客户端。我有一个为客户端“轮询”服务器的功能。每次客户端连接到服务器时,我都会向每个客户端发送一个命令来更新他们的在线列表。当客户端断开连接时,它会向每个客户端发送一个命令来更新他们的列表。基本上就像 msn-messenger。
  • 这是一个有趣的解决方案。但是,当您说“每当另一个客户端想要发送消息时,它都会发送接收者的 UniqueID 和消息。”,您的意思是它发送两条不同的消息,一条用于接收者的 UniqueID,一条用于消息,或者消息必须同时具有这两者信息以及消息的格式应该是什么?
  • 我制作了自己的格式。它是这样的: struct CMsg {unsigned long ID, Length, Command; char* 消息;};我将结构写入字节数组并将其发送到服务器。服务器读取 ID (sizeof(unsigned long)),然后是长度,然后是命令。最后,它读取“长度”数量的字符(消息)。
  • @Brandon 谢谢。你的解释对我帮助很大。但我还有一个问题。我不确定我可以在这里问,或者我应该提出另一个问题。我需要知道如果我想在另一个平台(如android)中编写另一个客户端应用程序,客户端可以发送什么消息?我们如何从 java 访问 CMsg 结构?

标签: c++ sockets client server


【解决方案1】:

实现此目的的一种方法是在通过实际服务器进行一些通信后,让其中一个客户端充当服务器。您需要创建自己的协议。话虽这么说:

1- 客户端 A:-嘿,服务器!。告诉客户端 B 创建一个通信服务器,以便我可以直接与他通信。

2- 服务器:-嘿,客户端 B!。启动一个服务器实例并告诉我连接属性,以便我可以中继客户端 A,以便他可以连接到您。

3- 客户端 B:-嘿,服务器!。我已准备好接受客户端 A 的连接请求。这是我的连接属性...

4- 服务器:-客户端 A!!这里是客户端B的连接属性。拿走还是走开……我已经完成了……

5- 客户端 A:-嘿,服务器 B!.. 我可以连接吗?..

那是协议..所以任何客户端首先向服务器发起一个请求,其中包含“我,请求连接到客户端x..”的消息类型。服务器命令客户端 x,客户端 x 响应,服务器将响应中继给发起者客户端......您还应该实施错误处理、拒绝策略或其他一些您能想到的东西,以管理整个协议。

【讨论】:

  • 如果两个客户端都无法启动服务器(在它们背后的防火墙上戳一个洞),那么可能无法将消息路由到客户端。在这种情况下,您可以尝试一些肮脏的技巧(从两端发送 UDP 数据包,然后查看是否可以接收“回复”),但没有真正保证的解决方案。
  • @Speed8ump UDP 数据包是邪恶的! :)) 客户端 B 可以在上面的第 3 阶段说“服务器,我无法创建通信服务器”,并且服务器可以在第 4 阶段中继“客户端 a,客户端 b 对您无法服务..”。或者如果客户端 b能够启动服务器,但如果有防火墙,服务器可以测试连接。 b 在第 3 阶段之后的属性,而不是在第 4 阶段说“这里是道具”,他可以说“客户端 b 已启动但无法连接”到客户端 a.. 是的,对此没有保证的解决方案。这就是为什么协议应该得到很好的管理..
【解决方案2】:
  1. 客户端 A 与服务器对话。
  2. 客户端 B 与服务器对话。
  3. 服务器确定 A 需要直接与 B 对话,反之亦然。
  4. 服务器向 A 和 B 发送一条消息,其中包含如何相互通信的详细信息(IP 地址、端口等)。消息还详细说明了(A 或 B)将发起联系、超时等。
  5. 收到后,每个 A 和 B 开始侦听服务器详细说明的端口。
  6. 消息中设置发起联系的人都会这样做(A 与 B 交谈,反之亦然)。

除非我完全错过了问题的重点。您需要定义一些新消息,其中包含 A 和 B 通话所需的所有详细信息并将其发送给 A 和 B,他们需要接收/处理消息并做出相应的反应。

【讨论】:

    【解决方案3】:

    将客户端-服务器通信视为旧的 Radio 通信。

    1. A 需要与 B 交谈,所以 B 一定在听
    2. A 结束他的演讲(您只需发送一个关键字,例如“//EOC”,或使用固定宽度的消息)。
    3. B 需要和 A 说话,所以 A 不能说话,让 B 和 A 说话

    迭代直到通信结束命令

    所以想象一下谈话是write,听是read

     B:  read  -> A:  write 
     A:  read  -> B:  write 
    

    记得使用关键字断开 2 个客户端,否则系统调用可能会出现一些不良行为

    【讨论】:

      猜你喜欢
      • 2013-02-21
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-15
      • 2012-11-02
      • 1970-01-01
      相关资源
      最近更新 更多