我正在尝试使用C从Java客户端向C服务器发送一些字符串。 首先,我发送字符串的长度。然后,我在C中手动分配内存 最后我按字符发送String字符。
问题有时我得到正确的字符串,有时我得到整个字符串+额外的其他未知字符(就像我分配的比我得到的多)。
这是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 :(得分: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
相同,这样就不会遇到编码问题。
答案 1 :(得分: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;
}