我可以通过TCP发送大约10,000~2,000字节的数据吗?我正在将图像(60 x 60)从Android客户端传输到linux服务器.在Android上似乎没问题.在服务器端,如果我尝试将图片数据发送回客户端,那么它不起作用.在客户端,如果我解析,那么我得到了一些我不应该得到的奇怪数字.
通过TCP传输大数据有任何技术问题吗?我该如何解决?提前致谢..
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;
}
Run Code Online (Sandbox Code Playgroud)
我这样得到char*并像这样发送它
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;
Run Code Online (Sandbox Code Playgroud)
你要做的事情很简单(20K不是"大").到目前为止,最常见的原因是这样的情况发生,被忽视的返回代码send和recv.你应该记住一些事情:
send(2)不能总是将所有数据从用户空间复制到内核空间.检查返回的值recv在获取所有数据之前,您需要进行几次实际上,在许多系统上,你可能会获得send大量数据(内核会嘲笑你的20K),但你必须在一个循环中接收.这是一个深受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;
}
Run Code Online (Sandbox Code Playgroud)
你似乎忘记了字数(正如Andrew Finnell怀疑的那样).对于每个整数,你应该在发送(之前memcpy)之前做这样的事情:
m_dataLength = htonl(m_datalength);
Run Code Online (Sandbox Code Playgroud)
这收到时:
m_dataLength = ntohl(m_datalength);
Run Code Online (Sandbox Code Playgroud)