2009-05-30 10 views
1

我正在向服務器發送兩次數據。首先,我發送「Hello world」,然後發送「服務器」。 但服務器在1次讀取時收到數據。但服務器必須在雙讀操作中讀取數據。如何在BlackBerry中將數據寫入套接字?

此外,我寫的數據。然後從服務器讀取數據,然後寫入數據。 在這種情況下,服務器可以讀取第一個數據。但服務器無法讀取第二個數據。 服務器使用讀取,寫入,讀取。

那麼如何解決這個問題呢?如何在BlackBerry中將數據寫入套接字?

回答

0

我得到的溶液來克服,以提取兩字符串

在發送器設備

  • 創建包含例如數據數據的細節 長度的報頭,數據類型等。
  • 這頭添加到實際的數據,並將其發送

在接收設備

  • 讀取頭
  • 從標題檢索實際數據長度
  • 讀下數據達到指定的數據長度
0

對於第一個查詢,我猜你正在使用TCP。如果你使用UDP,那麼服務器將按你想要的順序讀取數據包。

你能對第二個查詢更清楚/詳細嗎?

+2

UDP順序不能保證。你不能依賴它。 – chrish 2009-06-01 00:58:45

1

很難說沒有更多的細節,但它聽起來像你在第一種情況下使用單向通信 - 即客戶端寫入,然後再次寫入。有多種原因會導致服務器將2次寫入讀爲1次。在客戶端,無線堆棧(或BES)中的某處緩衝,在服務器端緩衝。所有這些都與TCP/IP合法。

不知道有關解決方案的更多信息,您是否想過定義一個小協議 - 即客戶端在發送第二個寫入之前寫入已知字節或字節(如0字節?)?然後服務器可以讀取,然後識別分隔字節,並說'aha,這是與客戶端不同的寫法'?

2

你描述的是默認情況下TCP應該如何工作。你看到的是Nagle算法(RFC 896)在工作,減少了發送的出站數據包的數量,因此它們被儘可能有效地處理。您可能在您的代碼中發送了2個數據包,但它們一起作爲1個數據包進行傳輸。由於TCP是一個字節流,接收者不應該對它得到的數據包做任何假設。您必須在更高級別的協議中分隔您的分組數據,並且接收器必須根據該協議處理數據。它必須處理多個數據包到達單個讀取,單個到達多個讀取以及之間的所有數據的情況,只在完全接收數據包數據時處理數據包數據,緩存任何剩餘的數據以供後續讀取處理需要。

0

我會嘗試明確地告訴Connector.open打開流爲read_write。然後,我會確保每次與服務器通話後都會刷新連接。

SocketConnection connection = (SocketConnection) Connector.open(url, Connector.READ_WRITE); 
OutputStream out = connection.openOutputStream(); 
// ... write to server 
out.flush() 
1

如前所述,這是一個預期的TCP行爲來節省帶寬。請注意,爲了提供您的包TCP增加了大量數據(例如目的端口,序列號,校驗和...)。

而不是刷新數據我建議你在協議中加入更多的工作。例如,您可以定義一個包含要讀取的字節數的頭,然後定義有效負載(實際數據)。

下面的代碼是在與該結構[長度]的串編碼的協議; [數據]

StringBuffer headerStr = new StringBuffer(); 
StringBuffer data = new StringBuffer(); 
//read header 
char headerByte = dataInputStream.readChar(); 
while (headerByte != ';') { 
    headerStr.append(headerByte); 
    headerByte = dataInputStream.readChar(); 
} 
//header has the number of character to read 
int header= Integer.parseInt(headerStr.toString()); 
int bytesReaded = 1; 
char dataByte = dataInputStream.readChar(); 
//we should read the number of characters indicated in the header 
while (bytesReaded < header) { 
data.append(dataByte); 
dataByte = dataInputStream.readChar(); 
bytesReaded++; 
}