2016-09-07 78 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

對不起,我應該提到只有一個客戶端。我的問題與實際處理傳入數據有關,因此它不會干擾我的主要線程和時間關鍵任務。希望有道理:) –