• mac tcp实现客户端与服务端进行图像传输及处理


    客户端发送图像到服务端,服务端对图像进行处理,在将处理后的图像发送到客户端,并且服务端持续监听客户端。

    客户端

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define PORT 8080
    #define BUFFER_SIZE 1024
    #define IMAGE_PATH "image.jpg"
    #define RESULT_IMAGE_PATH "result.jpg"
    
    int main() {
        int sock = 0, valread;
        struct sockaddr_in serv_addr;
        char buffer[BUFFER_SIZE] = {0};
    
        // 创建套接字
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            std::cerr << "Socket creation error" << std::endl;
            return -1;
        }
    
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(PORT);
    
        // 将IPv4地址从文本转换为二进制形式
        if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) {
            std::cerr << "Invalid address/ Address not supported" << std::endl;
            return -1;
        }
    
        // 连接到服务器
        if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
            std::cerr << "Connection Failed" << std::endl;
            return -1;
        }
    
        // 读取图像文件
        std::ifstream file(IMAGE_PATH, std::ios::binary);
        if (!file) {
            std::cerr << "Failed to open file: " << IMAGE_PATH << std::endl;
            return -1;
        }
        std::vector<unsigned char> imageData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    
        // 发送图像数据到服务器
        send(sock, imageData.data(), imageData.size(), 0);
        std::cout << "Image sent to server" << std::endl;
    
        // 关闭发送方向的连接
        shutdown(sock, SHUT_WR);
    
        // 接收服务器的处理结果
        std::vector<unsigned char> resultData;
        while (true) {
            valread = read(sock, buffer, BUFFER_SIZE);
            if (valread <= 0) {
                break;
            }
            resultData.insert(resultData.end(), buffer, buffer + valread);
        }
        std::ofstream resultFile(RESULT_IMAGE_PATH, std::ios::binary);
        resultFile.write(reinterpret_cast<const char*>(resultData.data()), resultData.size());
        resultFile.close();
        std::cout << "Result image received and saved as: " << RESULT_IMAGE_PATH << std::endl;
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    服务端

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define PORT 8080
    #define BUFFER_SIZE 1024
    
    void processImage(const std::vector<unsigned char>& imageData, std::vector<unsigned char>& resultData) {
        cv::Mat image = cv::imdecode(imageData, cv::IMREAD_COLOR);
    
        // 在这里进行图像处理,这里只是一个示例,将图像水平翻转
        cv::flip(image, image, 1);
    
        // 将处理后的图像编码为JPEG格式
        std::vector<int> params;
        params.push_back(cv::IMWRITE_JPEG_QUALITY);
        params.push_back(90);
        cv::imencode(".jpg", image, resultData, params);
        sleep(3);
    }
    
    int main() {
        int server_fd, new_socket, valread;
        struct sockaddr_in address;
        int opt = 1;
        int addrlen = sizeof(address);
        char buffer[BUFFER_SIZE] = {0};
    
        // 创建套接字
        if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
            perror("socket failed");
            exit(EXIT_FAILURE);
        }
    
        // 设置套接字选项,允许地址重用
        if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
            perror("setsockopt");
            exit(EXIT_FAILURE);
        }
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        address.sin_port = htons(PORT);
    
        // 绑定套接字到指定端口
        if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {
            perror("bind failed");
            exit(EXIT_FAILURE);
        }
    
        // 监听连接
        if (listen(server_fd, 3) < 0) {
            perror("listen");
            exit(EXIT_FAILURE);
        }
    
        while(1)
        {
            // 接受连接
            if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {
                perror("accept");
                exit(EXIT_FAILURE);
            }
            // 从客户端读取图像数据
            std::vector<unsigned char> imageData;
            while (true) {
                valread = read(new_socket, buffer, BUFFER_SIZE);
                if (valread <= 0) {
                    break;
                }
                imageData.insert(imageData.end(), buffer, buffer + valread);
            }
            std::cout << "Received " << imageData.size() << " bytes of image data" << std::endl;
    
            // 处理图像数据
            std::vector<unsigned char> resultData;
            processImage(imageData, resultData);
    
            // 向客户端发送处理后的结果
            send(new_socket, resultData.data(), resultData.size(), 0);
            std::cout << "Processed image sent to client" << std::endl;
            close(new_socket);
        }
        
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
  • 相关阅读:
    参与修谱工作,要具备哪些能力?光会修谱可不行
    SpringBoot 整合 Freemarker
    单链表(一篇带你掌握单链表)
    CF 111B Petya and Divisors
    Redis 发布订阅
    使用 Nginx 实现 URL 的重定向
    CSS_精灵图
    Linux操作系统网络模块
    TiDB 环境与系统配置检查
    【Agora UID 踩坑记录 && Java 数据类型】
  • 原文地址:https://blog.csdn.net/OEMT_301/article/details/137938837