C++ 如何通过TCP发送10000~20000字节的数据?
我可以通过TCP发送大约10000~20000字节的数据吗?我正在将一个图像(60乘60)从Android客户端传输到linux服务器。在安卓系统上,这似乎还可以。在服务器端,如果我试图将图片数据发送回客户端,那么它就不起作用。在客户端,若我解析,那个么我会得到一些不应该得到的奇怪数字 通过TCP传输大数据是否存在技术问题?我该如何解决这个问题? 提前谢谢C++ 如何通过TCP发送10000~20000字节的数据?,c++,tcp,C++,Tcp,我可以通过TCP发送大约10000~20000字节的数据吗?我正在将一个图像(60乘60)从Android客户端传输到linux服务器。在安卓系统上,这似乎还可以。在服务器端,如果我试图将图片数据发送回客户端,那么它就不起作用。在客户端,若我解析,那个么我会得到一些不应该得到的奇怪数字 通过TCP传输大数据是否存在技术问题?我该如何解决这个问题? 提前谢谢 char* PictureResponsePacket::toByte(){ /* * HEADER *
char* PictureResponsePacket::toByte(){
/*
* HEADER
*
* Magic number (4)
* Data length (4)
* Packet Id (2)
* Packet type (2)
* Device Id (48)
*
*/
/*
* BODY
*
* Nickname (48)
* deviceId (4)
* m_pictureSize
*/
int offset = 0;
int headerLength = sizeof(int) + sizeof(int) + sizeof(short) + sizeof(short) + 48;
int bodyLength = 48 + 4 + m_pictureSize;
int dataLength = headerLength + bodyLength;
m_dataLength = dataLength;
log("PictureResponsePacket::toByte(), data length %d \n", m_dataLength);
char *sendBuffer = new char[dataLength];
memset(sendBuffer, 0x00, dataLength);
char *ptr = sendBuffer;
/*
* -------------
* HEADER
* -------------
*/
/*
* Magic number
*/
memcpy(ptr + offset, m_magicNumberBuffer, sizeof(int));
offset += sizeof(int);
/*
* Data length
*/
memcpy(ptr + offset, &m_dataLength, sizeof(int));
offset += sizeof(int);
/*
* Packet id
*/
memcpy(ptr + offset, &m_packetId, sizeof(short));
offset += sizeof(short);
/*
* Packet type
*/
memcpy(ptr + offset, &m_packetType, sizeof(short));
offset += sizeof(short);
/*
*Device Id
*/
memcpy(ptr + offset, m_deviceId.c_str(), m_deviceId.size());
offset += 48;
/*
* -------------
* BODY
* -------------
*/
memcpy(ptr + offset, m_senderDeviceId.c_str(), m_senderDeviceId.size());
offset += 48;
memcpy(ptr + offset, &m_pictureSize, sizeof(int));
offset += sizeof(int);
memcpy(ptr + offset, m_pictureData, m_pictureSize);
offset += m_pictureSize;
return sendBuffer;
}
我用这种方式得到字符,然后像这样发送
char * sBuffer = reponsePacket->toByte();
int remainLength = reponsePacket->getDataLength();
int currentSentLength = 0;
SocketClient *client = work->getClient();
while(remainLength > 0){
if(remainLength >= MAX_LENGTH)
currentSentLength = send(client->getFd(), sBuffer, MAX_LENGTH, MSG_NOSIGNAL);
else
currentSentLength = send(client->getFd(), sBuffer, remainLength, MSG_NOSIGNAL);
if(currentSentLength == -1){
log("WorkHandler::workLoop, connection has been lost \n");
break;
}
sBuffer += currentSentLength;
remainLength -= currentSentLength;
你是说如果你把图像从Android发送到你的Linux机器上,你就可以成功地发送和读取它吗?如果不是这样,那么如果您的Linux服务器进程不是用Java编写的,这听起来可能是个问题 更新 由于cnicutar有一个很好的答案,我想提供一个替代方案,以避免手动执行协议
当使用它时,它将自动从主机转换到网络并返回。它也可以用来创建C++和java绑定。 < P>我认为
send
和recv
的返回码。你应该记住几件事:
无法始终将所有数据从用户空间复制到内核空间。检查返回值send(2)
- 数据不是在同一时间到达的,因此在获取所有数据之前,您必须进行几次
recv
的厄运,但您必须在循环中接收数据。这是一个深受Stevens readn启发的函数。使用它而不是recv
ssize_t
readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
/* Loop back and call read again. */
nread = 0;
else
/* Some other error; can't handle. */
return -1;
} else if (nread == 0)
/* EOF. */
break;
nleft -= nread;
ptr += nread;
}
return n - nleft;
}
当收到下列文件时:
m_dataLength = ntohl(m_datalength);
是的,你可以发送那个数量的数据,但通常不在一个包中。显示一些代码,可能会有很多问题。20kB是大数据吗?真的吗?除非有人告诉我我疯了,否则我还是会坚持认为问题的一部分是持久性。在发送之前,请签出所有值并将其转换为网络字节顺序。您仍然没有考虑Endian问题。Java总是大端的。x86上的本机代码理解little endian。我在这里留下我以前的评论,因为从技术上讲这是真的。但此代码只是一个网络流。“他仍然需要使用一个解码器来解决endian的问题。”安德鲁·芬内尔在OP编辑和添加代码之前回答道。事实上,他似乎没有像他应该的那样使用htons/htonl。在他发布代码之前,我们都不知道。在代码更新之前,我一直在猜测。因为你现在是我最完整的+1。
m_dataLength = ntohl(m_datalength);