2016-09-07 45 views
0

这可能是一个非常基本的问题/设计,但我正在努力处理我要在此定义的系统的正确方法。使用Linux的TCP客户端/服务器

我有一个系统与一个客户端(PC),将通过TCP/IP协议连接到嵌入式Linux板(树莓派)。这将是一个命令/响应系统,个人电脑会询问一些事情,树莓PI会回应结果。

例如:
CMD =>读取/返回ADC通道X

RSP => ADC通道X数据

对于这种类型的系统的我已经定义的分组协议,它允许此相互作用。我的问题是如何在Raspberry PI上处理这个问题。我想有一个单线程处理TCP连接;将接收数据放入线程安全队列并从线程安全队列中拉出输出数据。然后主线程会周期性地轮询队列以查找数据。当数据被发现时,该命令将被处理并且将生成响应。所有命令都有响应。

主线程还将执行其他时间关键任务(PID控制回路),因此它不能等待传入或传出数据。

我的猜测是这种类型的系统是相当普遍的,并且可能有一个很好的方法来实现这种类型的系统。我对Linux编程非常陌生,但我一直在编程高度嵌入式系统(无操作系统)。只是为了这种类型的设计而努力。

注意我选择了TCP/IP,因为它在失败的情况下处理重定向。在我的例子中,每个命令都有一个响应,所以如果使得设计更简单/更灵活,就可以使用UDP。

任何帮助,非常感谢。

+0

也应该提到命令的数量和数据包的大小会有很大的不同。所以这个系统需要运行整个应用程序运行的时间。有可能并不总是有一个客户端连接。 –

+0

无论如何,关键线程是否拥有这些数据?还是必须得到/计算它以对请求做出反应?如果数据已经可用,那么处理客户端的线程可以执行简单的读取/处理/写入循环,而不需要队列。 “进程”部分只会访问某些线程安全存储的数据。 –

+0

现在的问题有点宽泛。如果你尝试了,你会得到更高质量的答案,并写一篇关于你为什么不满意的文章。 – jxh

回答

2

我倾向于避免线程,如果我可以,并且只有在必须使用它们时才使用它们,因为它们会让程序更难调试。他们把决定性问题变成了非确定性问题。所以我最初的方法是看看我是否可以在没有线程的情况下完成并仍然实现并发。这可以使用select,当需要读取套接字上的某些内容时,它会通知您的主程序。然后,当套接字上有东西时,它可以读取数据,处理数据,并等待下一个事件。这种方法的问题在于,如果接收数据的计算时间超过了处理下一个数据元素的可接受时间,那么最终可能会在套接字上产生未处理的数据。如果发生这种情况,那么你可以继续在线程中运行接收循环,在另一个线程中运行工作函数,或者分叉一个新进程并处理来自新进程的数据副本。

+0

嗯,我喜欢这种方法。作为一名深度嵌入式开发人员,我从不使用线程我不知道选择的方法。这可以工作,如果选择不阻止。我现在会研究。 –

+0

由于OP引用的是linux,所以我觉得'epoll'可能是一个更好的选择......你怎么看? – Myst

+0

@Myst:是的,如果内核支持它,epoll就可以工作。我从来没有直接使用epoll,但使用了包装epoll的libevent。 – sashang

1

超经典的linux方法是让一个侦听器程序为每个新客户端分配一个新副本。 Linux甚至有一个内置的恶魔为你做了这个(initd - 尽管可能已经改变了所有systemd的东西)。多数民众赞成在sshd,telnetd,ftpd如何工作。没有线程

+0

对不起,我应该提到只有一个客户端。我的问题与实际处理传入数据有关,因此它不会干扰我的主要线程和时间关键任务。希望有道理:) –