如何通过TCP发送10,000~20,000字节的数据?

cod*_*ons 0 c++ tcp

我可以通过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)

cni*_*tar 5

你要做的事情很简单(20K不是"大").到目前为止,最常见的原因是这样的情况发生,被忽视的返回代码sendrecv.你应该记住一些事情:

  • 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)