簡體   English   中英

使用Boost :: Asio進行雙向TCP通信的程序結構

[英]Program structure for bi-directional TCP communication using Boost::Asio

首先,我希望我的問題有道理,甚至可能! 從我讀過的關於TCP套接字和Boost :: ASIO的內容來看,我認為應該如此。

我要做的是設置兩台機器,並在它們之間通過TCP實現雙向讀/寫鏈路。 任何一方都應該能夠發送一些數據供另一方使用。

關於TCP(/ IP?)的第一個令人困惑的部分是它需要這個客戶端/服務器模型。 然而,閱讀表明任何一方都能夠寫作或閱讀,所以我還沒有完全氣餒。 我不介意建立任意一方作為客戶端而另一方作為服務器。 在我的申請中,可以提前談判,而不是我擔心。

不幸的是,我遇到的所有示例似乎都集中在連接到服務器的客戶端上,並且服務器立即發回一些數據。 但我希望客戶端能夠寫入服務器。

我設想某種循環,其中我稱之為io_service.poll() 如果輪詢顯示另一方正在等待發送一些數據,它將調用read()並接受該數據。 如果隊列中沒有任何等待,並且它有要發送的數據,那么它將調用write() 雙方都這樣做,他們應該能夠互相讀寫。

我關心的是如何避免兩者同時進入某些同步write()操作的情況。 他們都有數據發送,然后坐在那里等待雙方發送。 這個問題只是暗示我應該只進行異步write()read()嗎? 在這種情況下,如果連接的兩端都試圖同時異步寫入,事情會爆發嗎?

我希望有人可以理想地:

1)提供一種非常高級的結構或最佳實踐方法,可以從客戶端和服務器的角度完成此任務

或者,理想情況下,

2)說我想做的事情是不可能的,也許建議某種形式的解決方法。

你想做的是絕對可能的。 Web流量是“客戶端”在服務器發送之前很久發送的情況的一個很好的例子。 我認為你被“客戶”和“服務器”這兩個詞搞砸了。

這些詞真正描述的是連接建立的方法。 在“客戶”的情況下,它是“活躍”的建立; 在“服務器”的情況下,它是“被動的”。 因此,您可能會發現使用“主動”和“被動”這兩個術語不那么令人困惑,或者至少以這種方式來考慮它們。

關於找到可以用作工作基礎的示例代碼,我強烈建議您查看W. Richard Stevens的“Unix網絡編程”一書。 任何版本都可以,但第2版將更新。 它只是C,但沒關系,因為套接字API只是C語言。 boost :: asio很不錯,但聽起來你可能會看到引擎蓋下的一些螺母和螺栓。

我關心的是如何避免兩者同時進入某些同步write()操作的情況。 他們都有數據發送,然后坐在那里等待雙方發送。 這個問題只是暗示我應該只進行異步write()和read()嗎? 在這種情況下,如果連接的兩端都試圖同時異步寫入,事情會爆發嗎?

聽起來你對如何使用協議感到有些困惑。 TCP僅提供可靠的字節流,僅此而已。 最重要的是,應用程序會說協議,因此他們知道何時以及要讀取和寫入多少數據。 如果雙方都沒有讀取數據,則客戶端和服務器同時寫入數據會導致死鎖。 解決該行為的一種方法是使用deadline_timer取消異步寫入操作(如果它在一定時間內沒有完成)。

編寫服務器時應該使用異步方法。 同步方法適用於某些簡單的客戶端應用程序。

TCP是全雙工的,這意味着您可以按照所需的順序發送和接收數據。 為了防止您自己的協議中的死鎖(程序的高級行為),當您有機會發送和接收時,您應該優先接收。 在級別觸發模式下epoll看起來像:發送和接收epoll,如果你可以接收,否則如果你可以發送並有東西發送這樣做。 我不知道boost :: asio或thread如何適合這里; 你需要對發送和接收如何交錯進行一些控制。

您正在尋找的詞是“非阻塞”,這與POSIX異步I / O(涉及信號) 完全不同。

這個想法是你使用類似fcntl(fd,F_SETFL,O_NONBLOCK) write()將返回成功寫入的字節數(如果為正), read()write()返回-1並設置errno = EAGAIN如果“無法進行”(沒有數據讀取或寫入窗口已滿) 。

然后使用select / epoll / kqueue之類的東西阻塞,直到套接字可讀/可寫(取決於設置的標志)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM