V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MekoPan
V2EX  ›  C++

问个关于 C++ socket 传输 Mat 图片的问题

  •  
  •   MekoPan · 2021-03-24 17:04:45 +08:00 · 1660 次点击
    这是一个创建于 1342 天前的主题,其中的信息可能已经有所发展或是发生改变。

    期望

    是实现客户端与服务端实现图片传输并显示

    目前实现

    **注:**测试图片宽为 481, 高为 640

    服务端

    char buf[481*640*3];
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        int total = 0;
        while(total < 481*640*3)
        {
        long len = recv(connfd, buf, 481*640*3, 0);
        total = total + len;
        }
        cout << "接收长度为: " << total << endl;
        break;
    }
    Mat img(640, 481, CV_8UC3, buf);
    imshow("sss", img);
    waitKey(0);
    

    客户端

    Mat img = imread("/img/1.jpg");
    int imgSize = img.cols*img.rows*img.channels();
    cout << imgSize << endl;
    
    char pos[imgSize];
    memcpy(pos, img.data, sizeof(pos));
    long sizelen = send(sockfd, pos, imgSize, 0);
    

    问题

    我理解的是 recv 函数返回的是 copy 完成的字节,send 发送数据过大时需要多次 recv.
    因此我在 recv 加了个循环保证接收到的字节数等于发送的字节数.但是当我把接收到的数据 Imshow 时出现了图片错误的情况,大概是图片只展示了一部分并且出现了图片复制这种情况.
    因为接触 C++不久,网上也查不到相关资料,因此写贴咨询一下,还请各位大佬不吝赐教,谢谢.

    Jirajine
        1
    Jirajine  
       2021-03-24 17:14:15 +08:00 via Android   ❤️ 1
    你都知道 recv 一次性可能接受不完,怎么 send 就只发一次呢。
    另外建议不要这样直接调用,易错还麻烦,用个 Qt/boost 这种封装好的且跨平台的库。
    exmario
        2
    exmario  
       2021-03-24 17:16:58 +08:00   ❤️ 1
    只说问题的话,sizelen 才是真正发送成功的长度,需要 while (sum<481*640*3)直到数据全部发完
    MekoPan
        3
    MekoPan  
    OP
       2021-03-24 17:20:53 +08:00
    @Jirajine 好的,谢谢老哥,我去了解一下这方面库
    MekoPan
        4
    MekoPan  
    OP
       2021-03-24 17:21:17 +08:00
    @exmario 谢谢老哥指点,我去改一下试试
    MekoPan
        5
    MekoPan  
    OP
       2021-03-24 17:25:21 +08:00
    @exmario
    ```C++
    int total = 0;
    while (total < imgSize)
    {
    long sizelen = send(sockfd, pos, imgSize, 0);
    total = total + sizelen;
    }
    ```
    关于 sizelen 我是这么改的,但是图片显示依然是有问题的 T.T
    borisz
        6
    borisz  
       2021-03-24 17:28:55 +08:00   ❤️ 1
    服务端 > long len = recv(connfd, buf, 481*640*3, 0);
    long len = recv(connfd, buf+totaol, 481*640*3-total, 0);
    注意偏移量呀
    mogg
        7
    mogg  
       2021-03-24 17:30:13 +08:00   ❤️ 1
    send(sockfd, pos + total, imgSize - total, 0);
    recv(connfd, buf+total, 481*640*3 - total, 0);
    传入的应该是要发送,要接受的首地址……
    ch2
        8
    ch2  
       2021-03-24 17:33:11 +08:00   ❤️ 1
    你 recv 的时候,得挪动第二个参数,要不然新的数据会覆盖旧的
    MekoPan
        9
    MekoPan  
    OP
       2021-03-24 17:33:15 +08:00
    @borisz 感谢老哥,问题解决了.忘了偏移量这个问题.非常感谢
    MekoPan
        10
    MekoPan  
    OP
       2021-03-24 17:33:45 +08:00
    @mogg 谢谢老哥指点,问题得到了解决.我忘记了偏移量这个问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1437 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:19 · PVG 01:19 · LAX 09:19 · JFK 12:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.