2012-10-10 78 views
-1

首先,我很新與網絡連接的sockects和TCP/IP數據包,如果能夠以非常清晰的方式解釋,我將不勝感激。我的機器人程序第一次嘗試與我們當前的機器人一起使用kinect,但是我們遇到了問題。目前他們用java編碼,而他們計劃用C++編寫kinect。是否可以使用TCP/IP數據包在兩種語言之間發送信息?我們需要一個C++客戶端和一個Java服務器。如果有人有鏈接或例子,我會很感激,謝謝!C++客戶端到Java服務器(TCP/IP)

+2

當然,TCP/IP與語言無關。但是,如果Java和C++部分都運行在同一臺機器上,那麼可以考慮使用[Java Native Interface](http://en.wikipedia.org/wiki/Java_Native_Interface)在C++中創建Kinect接口並使用Java通過JNI使用它。 –

+0

如果你是網絡,但你不需要JNI,因爲你將通過套接字進行通信。 – OmniOwl

+1

java的套接字示例是通用和平凡的。 C++的目標是什麼?視窗? LINUX? – ChrisCantrell

回答

1

Java和C/C++之間溝通的真正問題是字節順序問題。如果要發送二進制數據,則必須清楚完整地設計通信結構,包括數字大小(以字節爲單位),位順序(lsb/msb,交換字節或不交換字節,簡稱,整數和longs)和結構打包(結構中的字段之間的填充字節數)。

如果你能避免它,我建議你不要用二進制通信。有兩個原因:

  1. 無需擔心位順序,字節交換和結構打包。
  2. 在不解碼數據的情況下竊聽通信。這裏仍然有ascii/unicode問題。

EDIT 在C/C++,數據被存儲在的方式,使CPU訪問快速和容易。類/結構的字段在字邊界上對齊(因爲大多數CPU只能訪問全字塊中的內存),並且這些位的排列順序與CPU相匹配。但是,CPU可以具有不同的位順序和字長(16,32,64,...)。大多數英特爾CPU都是小端,而其他大多數設計都是大端。爲了讓生活更有趣,Java虛擬機在每個平臺上都是大端的。 http://en.wikipedia.org/wiki/Endianness

因此,如果您希望兩臺C/C++機器能夠通信,那麼您必須以可以讀取它的方式發送數據。通常,要在異構環境中進行通信(稱爲'over the wire'),您需要指定所有通信都以特定格式完成。 TCP/IP使用MSB(最高有效位)排序。所有程序然後必須從線格式翻譯(如果需要)。

由於CPU在字長塊中佔用內存,編譯器會在填充整個機器字的字段之間放置填充字節。對於讀取32位字的機器,採用如下結構:

struct example1 { 
    char someFlag; 
    int someCount; 
}; 

實際上需要8個字節的內存。第一個字段由單個字節的數據和3個填充字節組成,因此整數引用在字邊界上對齊。如果一個天真的通信器試圖發送這個結構中的數據,比如說send(&example1, sizeof(example1));到另一個具有不同字長或字節順序的系統,那麼其他系統的read(&example1, sizeof(example1));,則example1.someCount的值可能會與預期的非常不同。

大部分情況通常都是學術性的,直到您將Java放入其中。因爲Java總是MSB格式。因此,即使在相同的硬件上,從C/C++應用程序發送到Java應用程序也可能會導致這種意想不到的結果。

Java包含我最喜歡的I/O類,java.nio.ByteBuffer。它能夠從幾乎任何來源讀取整數,長整數,浮點數和雙精度。如果您知道數據是如何創建的,則會讀取它。 ByteBuffer有getShortgetInt等方法來獲取任何類型,以及order()方法來設置數據的字節順序。

+0

我真的很感謝幫助的人,只是爲了擴大你的回答@Zagrev:如果我從kinect發送數據到機器人(java),我不需要使用二進制數據發送它嗎?如果不是,我將如何發送信息? –

0

當然,您可以在不同語言的程序之間交換信息。 (你有沒有想到,整個互聯網使用Java?)

這裏是我谷歌搜索 「socket編程{Java和C++}」 後發現:

http://codebase.eu/tutorial/linux-socket-programming-c/ - 似乎是OK

http://www.javaworld.com/jw-12-1996/jw-12-sockets.html - Java教程

但要小心。根據您的硬件架構,當交換二進制數據時(字節順序等),您可能會遇到一些問題。當你使用面向對象的語言時,你可以考慮使用某種處理低層通信的中間件 - 例如Ice。但是,這可能是一個矯枉過正的情況。

1

無論何時您希望兩個程序通過網絡與對方通話,您都需要定義一個protocol

在TCP之上定義的協議需要指定一種方式來告訴接收方收到整個消息的時間。兩種常用的方法是:

  • 指定一些特定的數據序列來表示「結束」。一個例子是HTTP,它利用特殊的CRLF字符來表示消息的非有效載荷部分的結束。
  • 在消息的某個預定義部分指定消息的長度。一個例子是指定「Content-Length」標題中有效載荷長度的HTTP。

你可以找到關於HTTP報文結構在這裏更多的信息:http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

而且你可能會喜歡的編碼有效載荷的平臺無關的格式。一個很好的二進制格式是Google協議緩衝區,它在Java和C++中得到很好的支持:http://code.google.com/p/protobuf/