【发布时间】:2018-08-02 18:38:16
【问题描述】:
我又问了其中一个问题:P
由于我正在将我的 C++ 服务器移植到 Java 服务器(并且几乎完成),我只缺少一件事:
发送文件。
我不知道如何在 Java 中构造数据包以通过 DataOutputStream 发送它。
在 C++ 中,我以这种方式准备了数据包(为 file_size 保留前 4 个字节,其余的文件本身):
char *pData = new char[file_size];
memcpy(pData, charArray.data(), file_size);
char *packet = new char[file_size + 4];
memset(packet, 0, file_size + 4);
*(int*)(packet) = file_size;
memcpy((char*)(packet + 4), pData, file_size);
int r = file_size + 4;
sendall(stream, packet, &r);
我希望你能在这里帮助我,我能够构造简单的数据包,但是这个让我头疼 :P
我是合并字节还是如何在 Java x..x 中完成 C++ 代码
提前致谢!
发送函数:
int sendall(TCPStream *s, char *buf, int *len)
{
int total = 0;
int bytesleft = *len;
int n;
while(total < *len)
{
n = s->send(buf+total, bytesleft);
if (n == -1) break;
total += n;
bytesleft -= n;
}
*len = total;
return n ==-1 ? -1 : 0;
}
【问题讨论】:
-
那么问题是什么?您发送 4 个字节的大小,然后是文件内容的所有字节。您是否在问如何以正确的字节顺序发送 4 字节大小?您正在使用
DataOutputStream,它首先发送带有高字节的int值,所以如果这是C++ 所做的,则调用writeInt(int v),然后调用write(byte[] b, int off, int len)。如果 C++ 先发送低字节,那你为什么要使用DataOutputStream? -
既然你在移植你可能不关心C++笔记,但是,从
charArray.data()复制到pData有什么意义呢?看起来你可以节省一个步骤和memcpy((char*)(packet + 4), charArray.data(), file_size);,或者省去很多麻烦,然后分别发送file_size和charArray.data()。 TCP 是一个流,因此除非您在sendall中添加了额外的协议标头,否则您决定什么是数据包并不重要。 TCP 会以它想要的任何大小/形状的 blob 发送您的消息。 -
再想一想,这也适用于java。
sendall是做什么的?如果它只是标准套接字写入的精简包装,您可以将所有工作减少到一个DataOutputStream,一个调用writeInt和一个调用write。如果没有sendall的代码或猜测,则无法回答问题。 -
Except for Endian. 传输
file_size时注意字节序。 Java 总是说大端,除非你告诉它不这样做。 C++ 能说出硬件的原生特性。 -
C++ 代码可以简化为
sendall(stream, (char*)&file_size, sizeof (file_size)); sendall(stream, charArray.data(), file_size);。再次注意字节序并确保int是 32 位的。 Better still useuint32_tfrom<cstdint>
标签: java c++ sockets tcp tcpserver