2012-04-23 62 views
3

我想從Java客戶端發送一些字符串到C服務器使用C. 首先我發送字符串的長度。然後,我在C 中手動分配內存,最後我按字符發送字符串。發送字符串從Java到C(套接字)

有時我得到正確的字符串的問題,有些時候我得到整個字符串+額外的其他未知的字符(就像我分配超過我得到的)。

這裏是Java代碼:

protected void send(String data){ 
    short dataLength=(short)data.length(); 
    try { 
     out.write(dataLength); 
    for (int i=0; i<data.getBytes().length ;i++) 
    { 
     out.write(data.getBytes()[i]); 
    } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  
} 

這裏是C代碼:

void read4(int sock, int *data) 
{ 

    char dataRecv; 
    char* memoireAllouee=NULL; 
    int stringLength; 
    int i=0; 
    recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ; 
    *data = dataRecv; 
    stringLength=dataRecv; 
    memoireAllouee=malloc(sizeof(char)*stringLength); 
    if (memoireAllouee==NULL) 
    { 
     exit(0); 
    } 
    for (i=0;i<stringLength;i++) 
    { 
     recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ; 
     *data = dataRecv; 
     memoireAllouee[i]=dataRecv; 
    } 
    printf("\n\n%d\n\n\n",stringLength); 
    printf("\n%s\n",memoireAllouee); 
} 

如果你還認爲這種方法是不是最佳的,你可以幫我更快嗎?

+0

@trutheality:如果您將每個例程中涉及的行復制並粘貼到答案中,那將會是一個非常優秀的答案。 – sarnold 2012-04-23 00:13:24

+1

@sarnold我看了一下文檔,它看起來像'out'可能是['DataOutputStream'](http://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream。 html),如果是這樣,匹配方法是「write(int)」,它將int的最低8位寫入流中。這就解釋了爲什麼長度被正確傳輸(或接近它,如果真的發送「短」的話會更糟糕)。這也意味着轉換爲'short'或者是完全不必要的,或者試圖在存儲長度的臨時變量中保存16位空間。 – trutheality 2012-04-23 05:19:01

+0

@truthreality:你的答案是賴特人!我非常愚蠢,我沒注意C方的字符。 所以這發生了什麼:當我發送一個字符串<127字符串每一件事情都可以,當我發送一個字符串> 127字符時,會發生很多隨機事件......(寫入字符串和其他奇怪的字符串,根本不寫字符串, ...) 再次謝謝。 啊,只是另一件事,信息(爲他人)。我已將short轉換爲2個字節的數組併發送給它。 – user655561 2012-04-23 14:10:02

回答

4

要回答你的第二個問題:

for (int i=0; i<data.getBytes().length ;i++) 
{ 
    out.write(data.getBytes()[i]); 
} 

應該只是:

out.write(data.getBytes()); 

for (i=0;i<stringLength;i++) 
{ 
    recv(sock, (char*)&dataRecv, sizeof(dataRecv), 0) ; 
    *data = dataRecv; 
    memoireAllouee[i]=dataRecv; 
} 

應該是:

int offset= 0; 
while (offset < stringLength) 
{ 
    int count = recv(sock, &memoireAllouee[offset], stringLength-offset 0) ; 
    if (count == 0) 
     // premature EOS .. do something 
     break; 
    if (count == -1) 
     // Error ... do something 
     break; 
    offset += count; 
} 
+0

非常感謝 – user655561 2012-04-23 14:10:34

9
protected void send(String data){ 
    short dataLength=(short)data.length(); 
    try { 
     out.write(dataLength); 
    for (int i=0; i<data.getBytes().length ;i++) 
    { 
     out.write(data.getBytes()[i]); 
    } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  
} 

對於初學者來說,你重新計算整個getBytes()陣列兩次每個字符。將byte[]保存到一個變量byteArray並使用它 - 你完全不必要地使這個過程保持平方時間。另外,爲什麼不直接撥打out.write(byteArray),而不是做for循環?其次,data.length()並不總是等於data.getBytes().length()。確保你寫的是byteArray.length而不僅僅是data.length()

最後,確保你在兩端使用一致的字符集。字符串到字節數組的映射很大程度上依賴於Charset,所以請確保它在兩邊都是相同的Charset,因此您不會遇到編碼問題。