3

我正在尝试使用 C 将一些字符串从 Java 客户端发送到 C 服务器。首先我发送字符串的长度。然后,我在 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);
}

如果您还认为这种方法不是最佳方法,您能帮我用一个更快的方法吗?

4

2 回答 2

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();
    }       
}

对于初学者,您要为每个 charactergetBytes()重新计算整个数组两次。将 保存到一个变量并使用它——你正在让它花费二次时间,完全没有必要。另外,为什么不直接调用,而不是循环呢?byte[]byteArrayout.write(byteArray)for

其次,data.length()并不总是等于data.getBytes().length()。确保你正在写作byteArray.length而不是仅仅data.length().

最后,确保您在两端使用一致的字符集。字符串到字节数组的映射在很大程度上依赖于Charset,所以要确保它Charset在两边都是一样的,这样你就不会遇到编码问题。

于 2012-04-23T00:08:48.620 回答
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;
}
于 2012-04-23T01:37:26.663 回答