2009年3月6日 星期五

用c++封裝socket

因為socket均是用c去實作,基本上是function導向的。
因為我必需要用到Qt去顯示介面,所以為了以後方便使用,我還是先學習如何用c++來封裝socket,到時候若真的有必要的時候,可以直接拿來用啦~

因此,最近找了許多c++來完成封裝socket的程式,最有幫助的應該是以下這一個網頁。
Linux Socket Programming In C++
最後我參考了這一個資料(chart application),完成了傳送檔案的程式,再來完成了傳送struct的程式,最後,在Qt的介面下完成了傳送webcam frame的程式。

本來要寫的清楚一點,但是,因為別人早就寫的很好了,大家參考他的就好了。

我這裡要說的是在server透過tcp的方式傳送給client時,我所遇到的問題。

1. 傳送封包不完美
我一開始的想法是由server透過accept()等待client端的connect(),當連線建立之後,server端就一直傳送切好的packet給client,然後,client端就一直接收就好了。
但是,確出現錯誤啦。原本server與client均在本機端時,執行沒有問題(先透過傳送一個frame),但是,當server與client在不同主機上時,確發現會出現中斷。
這個時候,我只好先拿傳送檔案的程式,在server-clinet在不同主機上會不會出現錯誤,竟然發現檔案接收不完整。原本我以為tcp是標榜可信賴傳送,所以,server一直傳,client一定會準確的收到。我猜想可能是server一直傳,client來不及接收,導致buffer不能容納那麼多資料,就會導致crash。
知道問題點之後,馬上重新設計,當server端與client端收到對方的封包之後,會回傳"I got it"的字串。
舉一個例子:
當server端送出一個packet之後,就等待client回傳"I got it"字串,這樣可以避免server端一直送出訊息,而導致client來不及接收所發生的錯誤。

2. blocking的問題:
同時,也意外的發現,這一個方法可以避免blocking的問題發生,因為,blocking雖然是接收到資料之後,不會馬上傳送而等到buffer滿了之後,才會傳送,但是,這一個等待的時間也有一定的限制。而透過上面這一個方法就可以解決blocking的問題。那為什麼不設定成non-blocking呢?因為設定成non-blocking的情況的話,會有一堆情況要自己處理,會比較複雜。

例如buffer大小是1024,如果只有7byte要傳送的話,本來不會馬上傳送出去,但是,下一個指令是等待對方client回傳"I got it"字串,所有必需等待,結果時間一到,就不得不送出去啦~算是可以不必用non-blocking的方式做到「類」non-blocking的功能!!

主要參考資料:
Linux Socket Programming In C++

非常有參考的資料:
[C/C++] Socket Connection
[C/C++] Scoket Programming : Non-Blocking Communation
A Stream Socket API for C++
Linux Socket Programming 淺談 -- 教你的程式如何透過網路溝通

參考資料:
socket c++
sockets_test.cpp
C++ Sockets Library
Linux man:Send
QT中的SOCKET编程

沒有留言: