2012-04-23 72 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,因此您不会遇到编码问题。