C++ Mat的tcp发送缓冲区出错

C++ Mat的tcp发送缓冲区出错,c++,opencv,tcp,C++,Opencv,Tcp,我正试图通过TCP发送Mat图像。首先将Mat转换为uchar格式,然后转换为char格式。整个char格式的图像将被一个1024字节的缓冲区发送出去。下面是我的代码 Mat decodeImg = imdecode(Mat(bufferFrame), 1); uchar *transferImg = decodeImg.data; char* charImg = (char*) transferImg; int length = strlen(charImg); int offset = 0

我正试图通过TCP发送Mat图像。首先将Mat转换为uchar格式,然后转换为char格式。整个char格式的图像将被一个1024字节的缓冲区发送出去。下面是我的代码

Mat decodeImg = imdecode(Mat(bufferFrame), 1);

uchar *transferImg = decodeImg.data;
char* charImg = (char*) transferImg;
int length = strlen(charImg);
int offset = 0;
while (true)
{
    bzero(bufferSend, BUFFER_SIZE);

    if (offset + BUFFER_SIZE <= length)
    {
        for (int i = 0; i < BUFFER_SIZE; i++)
        {
            bufferSend[i] = charImg[i + offset];
        }
        //          memcpy(charImg+offset, bufferSend,BUFFER_SIZE);
        if (send(sockfd, bufferSend, sizeof(bufferSend), 0) < 0)
        {
            printf("Send FIle Failed,total length is%d,failed offset is%d\n",
                   length,
                   offset);
            break;
        }
    }
    else
    {
        for (int i = 0; i < length - offset; i++)
        {
            bufferSend[i] = charImg[i + offset];
        }
        if (send(sockfd, bufferSend, sizeof(bufferSend), 0) < 0)
        {
            printf("Send FIle Failed,total length is%d,failed offset is%d\n",
                   length,
                   offset);
            break;
        }
        break;
    }
    offset += BUFFER_SIZE;
}
Mat decodeImg=imdecode(Mat(bufferFrame),1);
uchar*transferImg=解码img.data;
char*charImg=(char*)transferImg;
整数长度=strlen(mg);
整数偏移=0;
while(true)
{
bzero(bufferSend,BUFFER_SIZE);

if(offset+BUFFER_SIZE在这里拉出水晶球。这可能是OP的问题,但如果不是,这肯定是一个需要解决的问题

Mat decodeImg = imdecode(Mat(bufferFrame), 1);
uchar *transferImg = decodeImg.data;
获取数据。如果这是你需要发送的,这是个不错的主意

char* charImg = (char*) transferImg;
从上面获取字节数组,并将其视为字符数组

int length = strlen(charImg);
矩阵数据不是ascii格式的数据,不是字符串,因此不应将其视为字符串

strlen
对数据进行计数,直到它到达一个空字符,一个数值为0的字符,它在正常的字母数字世界中不存在,因此可以用作一个金丝雀值来表示字符串的结束。计数是字符串中第一个空字符之前的字符数

在这种情况下,我们没有字符串。我们有一个二进制数的blob,其中任何一个都可能是0。任何地方都可能有空值。可能在开头。可能在中有100个字节。在读取所有有效图像数据后很长时间内,中可能不会有空值

无论如何,
strlen
几乎肯定会返回错误的值。字节太少,接收器无法获取所有图像数据,我也不知道它是做什么的。我们无法使用该代码。它可能会心烦意乱并丢弃结果。可能会崩溃。无法知道。如果信息太多,我们也不知道w发生了什么。也许它处理文件很愉快,忽略了发送的额外垃圾。也许它崩溃了

但是,如果它在有足够字节时关闭TCP/IP连接会怎么样?这会使发送方试图将少量未发送和不需要的字节写入一个关闭的套接字。
send
将失败,并将错误代码设置为socket closed

解决方案:

获取正确大小的数据

我从openCV文档中读到的是Mat中的
Mat::elemSize
,它将给出矩阵中每个项目的大小,并且
Mat::size
返回一个包含行和列的
size
对象。将
rows*columns*elemSize
相乘,您应该有要发送的字节数

编辑

如果是这种情况,您可能需要这样做唯一的问题应该是服务器无法识别图像。但是,当前的问题是此客户端无法发送整个缓冲区。什么是
bufferFrame
?您不应该发送
imencode
d char buffer吗?系统调用总是失败,原因是您可以查询:e> errno
。使用
strerror(errno)
perror
。你应该阅读他们的文档。@black奇怪的是,两个人怎么能在提问一小时后在同一时间发表本质上相同的帖子。是的。应该先用谷歌搜索一下。一定有人以前遇到过这个问题。结果证明我的答案是一个冗长的重复。嗯,对一个who不知道OpenCV!事实上,我一直看到发送base64编码数据,但在这方面你似乎比我知道得多…感谢你指出我从未意识到的这个问题。我目前的想法是可以将Mat转换为jpg格式并发送jpg吗?因为我的原始代码是发送一个jpg文件,所以从磁盘读取文件要花费更多的时间,我现在要做的是将存储在内存中的Mat格式的结果直接发送到客户端。@Miki我生命的一半时间似乎都花在打开套接字和发送不同类型的数据上。@wuyang您应该能够将jpg编码到内存缓冲区,然后将内存缓冲区写入套接字et.应该比发送未压缩的mat数据快得多,但如果担心保真度,jpg压缩将略微损坏数据。