【问题标题】:Minimising client processing - c socket programming最小化客户端处理——c socket编程
【发布时间】:2015-07-30 19:50:14
【问题描述】:

我正在研究基于 Berkeley 套接字的客户端/服务器模型,并且几乎完成了,但我坚持使用一种方法来知道已收到所有数据,同时最大限度地减少在客户端执行的处理。

我正在使用的客户端的内存和电池非常少,并且将部署在远程条件下。这意味着我会尽可能避免在客户端进行处理(以及电池损耗)。客户端的以下情况不在我的控制范围内:

  • 客户端一次发送它的数据 1056 个字节,直到它用完要发送的数据 (我不知道数字 1056 是从哪里来的,但如果你认为你知道我会非常有兴趣)

  • 客户端发送数据的时间非常难以预测(它连接到野生动物并根据连接强度和电池寿命发送数据)

    李>
  • 客户端在任何给定时间都有未知数量的数据要发送

  • 数据通过启用 GRSM 的电话标签传输(不确定这是否相关,但我假设额外的信息只能提供帮助)

  • (我正在模拟我希望通过 localhost 从客户端接收的数据,如果它似乎有效,我会询问我在哪里实习的公司投资静态 IP 地址以允许“ real” tcp 传输,如果不是,我不会。我认为这无关紧要,但同样,我宁愿提供太多信息而不是太少)

目前,我正在使用 while 循环并增加接收到的字节数,以便“recv()”每个 1056 字节部分。我的问题是服务器需要接收未知数量的这些。对我来说,最明显的解决方案是在来自客户端的初始标头中发送要接收的部分的数量,或者以某种方式标记要发送的最后一个部分。但是,这两种方法都需要在客户端进行处理,我想知道是否有办法检查客户端是否已从服务器端关闭其套接字?或者甚至在没有来自客户端的信息的情况下,在预先确定的一段时间后关闭与服务器的连接之类的事情是否可行?如果这些都不可能,那么我很想听听任何其他建议。

TLDR:我可以在此处使用什么条件来最大限度地减少客户端处理

while(!(/* Client has ran out of data to send*/)) {
    receive1056Section();
}

另外,我知道创建一个stackOverflow帐户并立即提出问题是不好的做法,我不知道还能做什么,对不起。如果我遗漏了一些非常明显的事情,请不要犹豫。

【问题讨论】:

  • 如果你有一个面向连接的传输 (TCP),你不需要关心数据包的大小(这意味着你的库确实关心)。如果您需要将处理保持在最低限度,请考虑使用 UDP。
  • 不确定我是否理解?为什么实现一个协议需要更多的进程?鉴于通信的错误......“不稳定”性质,我想知道 TCP 是否是最好的协议?小的UDP数据包可能更好?一些数据丢失有关系吗?
  • 我不认为我可以使用UDP,因为正在传输的数据是跟踪动物的卫星坐标,我的理解是UDP不保证传输顺序,这将是一个问题。另外,我只是一个实习生,被告知要做 tcp,他们可能有其他原因需要他们没有告诉我的工作 tcp 服务器。
  • 我问过 UDP 是否会是更好的选择,而 UDP 的问题是不能保证数据包确实到达服务器。显然,由于动物经常在水下或在 GRSM 覆盖范围非常有限的地方,因此确认数据实际上已到达服务器以避免数据丢失非常重要。
  • 这对于 GPS 坐标和设备/动物 ID 来说是很多字节:(无论如何,如果您坚持使用 TCP,我建议将通信保存在独立的应用程序协议单元中,这样可以独立于任何套接字打开/关闭进行解析和处理。降低客户端整体功耗的特定设计将需要比 SO 可以合理预期提供的更多信息和更多工作。

标签: c sockets tcp


【解决方案1】:

以下是关于如何进行交互的建议:

客户:

客户端通过 tcp 连接到服务器。

客户端发送数据块,直到所有数据都发送完毕。在每个块之后刷新发送缓冲区。

完成后,客户端在套接字上发出shutdownsleeps 几秒钟,然后关闭连接。

客户端然后休眠直到下一次传输。如果传输不成功,睡眠时间应该更短,以防止未发送的数据溢出可用内存。

如果客户端长时间无法连接,您将不得不丢弃不适合内存的数据。

我假设sleep 会降低功耗。

服务器:

除非您需要大规模的可扩展性,否则服务器程序可以是单线程的。它正在监听约定端口上的传入连接。

每当客户端连接时,都会创建一个新的套接字。

使用select() 查看哪些套接字有数据(不要忘记包括监听套接字!),以及从套接字读取的非阻塞读取。

当您收到相应的错误(没有更多数据要读取并且另一端有 shutdown 它是连接的一端)时,您可以关闭该套接字。

这应该可以在多达几千个同时 连接时正常工作。

Example that handles many of the difficulties of implementing a server

【讨论】:

  • 非常感谢您的回答。客户端有一个非常基本的操作系统,我不确定我将如何编写关闭函数,是否有其他方法可以做到这一点?
  • 我不熟悉 GRSM。事实上,我什至从未听说过它。如果客户端不能使用 tcp 套接字,那么您应该考虑将问题重新标记为更合适的(电话)标签。
  • 如果客户端不需要从套接字读取,您可以使用close 并跳过shutdownshutdown 用于表示您已完成发送数据,但您可能仍想阅读回复。
  • 据我所知,使用 GRSM 的问题与使用没有静态 IP 地址的东西相同。从服务器向客户端发送信息仍然是基于 tcp 的,但是您使用什么 ip 地址来建立连接?一旦客户端建立了连接,就可以正常进行传输了。这是否使它脱离主题?关闭的问题与 GRSM 无关,关闭它是操作系统定义的函数(linux 内核中的 sysvinit)。客户的操作系统没有这个,我必须自己写这个。问题是我不知道怎么做。
  • 如果你的答案是完美的,我会接受的。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多