OpenCV 이미지 Receiver 예제 (TCP 기반)
21 Aug 2018 | C++OpenCV 이미지 Receiver 예제 (TCP 기반)
OpenCV 이미지를 다운로드한다기보다는 일반적인 파일을 다운로드(TCP 기반) 하는 예제입니다.
CMakeLists.txt
cmake_minimum_required(VERSION 3.12) project(ImageTcpReceiver) set(CMAKE_CXX_STANDARD 14) add_executable(ImageTcpReceiver main.cpp ImageServer.cc ImageServer.h ClientHandlerThread.cc ClientHandlerThread.h) target_link_libraries(ImageTcpReceiver pthread)
ImageServer.h
#ifndef IMAGETCPRECEIVER_IMAGESERVER_H #define IMAGETCPRECEIVER_IMAGESERVER_H #include "ClientHandlerThread.h" #include <thread> #include <vector> using namespace std; class ImageServer { public: ImageServer(); ~ImageServer(); void start(); void stop(); private: bool initAcceptSocket(); void finAcceptSocket(); void run(); bool mIsRunning; thread mAcceptorThread; int mSocketId; vector<shared_ptr<ClientHandlerThread>> mClientList; }; #endif //IMAGETCPRECEIVER_IMAGESERVER_H
ImageServer.cc
#include "ImageServer.h" #include <iostream> #include <sys/socket.h> #include <zconf.h> #include <arpa/inet.h> const int PORT = 10050; ImageServer::ImageServer() { mIsRunning = false; mSocketId = -1; mClientList.clear(); } ImageServer::~ImageServer() { } void ImageServer::start() { cout << "ImageServer::start() " << endl; mAcceptorThread = std::thread(&ImageServer::run, this); } void ImageServer::stop() { cout << "ImageServer::stop() " << endl; mIsRunning = false; if (mAcceptorThread.joinable()) { mAcceptorThread.join(); } } bool ImageServer::initAcceptSocket() { cout << "ImageServer::initAcceptSocket() " << endl; struct sockaddr_in loc_addr = {0}; loc_addr.sin_family = AF_INET; loc_addr.sin_addr.s_addr = htonl(INADDR_ANY); loc_addr.sin_port = htons(PORT); mSocketId = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; int error; error = setsockopt(mSocketId, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)); if (error < 0) { perror("AcceptSocket - setsockopt(mSocketId, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT) Failed"); return false; } error = bind(mSocketId, (struct sockaddr *) &loc_addr, sizeof(loc_addr)); if (error < 0) { return false; } error = listen(mSocketId, 1); if (error < 0) { return false; } cout << "Server Socker is binding to " << PORT << ". " << endl; return true; } void ImageServer::finAcceptSocket() { cout << "ImageServer::finAcceptSocket() " << endl; if (mSocketId > 0) { shutdown(mSocketId, SHUT_RDWR); close(mSocketId); mSocketId = -1; } } void ImageServer::run() { bool ret = initAcceptSocket(); if (ret == false) { cout << "Creating Accept Socket is failed." << endl; return; } struct sockaddr_in client_address; socklen_t client_len = sizeof(client_address); int clientSocketId; mIsRunning = true; while (mIsRunning) { cout << "Waiting Client..." << endl; //clientSocketId = accept(mSocketId, (struct sockaddr *) &rem_addr, &opt); clientSocketId = accept(mSocketId, (struct sockaddr *) &client_address, &client_len); if (mIsRunning == false) { break; } if (clientSocketId > 0) { char clntName[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &client_address.sin_addr.s_addr, clntName, sizeof(clntName)); cout << "Client is Connected. (" << clientSocketId << ")"<<endl; shared_ptrclientHandler(new ClientHandlerThread(clientSocketId)); clientHandler->start(); mClientList.push_back(clientHandler); } } finAcceptSocket(); } </pre>
## ClientHandlerThread.h#ifndef IMAGETCPRECEIVER_CLIENTHANDLERTHREAD_H #define IMAGETCPRECEIVER_CLIENTHANDLERTHREAD_H #include <thread> using namespace std; class ClientHandlerThread { public: ClientHandlerThread(int socketId); virtual ~ClientHandlerThread(); void start(); void stop(); private: void run(); void savePacketAsFile(string filepath); thread mThread; bool mIsRunning; int mSocketId; }; #endif //IMAGETCPRECEIVER_CLIENTHANDLERTHREAD_H
## ClientHandlerThread.cc#include "ClientHandlerThread.h" #include <iostream> #include <sys/socket.h> #include <sys/types.h> #include <sys/time.h> #include <zconf.h> ClientHandlerThread::ClientHandlerThread(int socketId) { mSocketId = socketId; mIsRunning = false; thread_local int optval = 1; setsockopt(mSocketId, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); } ClientHandlerThread::~ClientHandlerThread() { } void ClientHandlerThread::start() { cout << "ClientHandlerThread::start() " << endl; mThread = thread(&ClientHandlerThread::run, this); } void ClientHandlerThread::stop() { cout << "ClientHandlerThread::stop() " << endl; mIsRunning = false; } void ClientHandlerThread::run() { mIsRunning = true; while (mIsRunning) { struct timeval tp; gettimeofday(&tp, NULL); long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000; char filename[256] = ""; sprintf(filename, "image_%ld.jpg", ms); savePacketAsFile(filename); } } void ClientHandlerThread::savePacketAsFile(string filepath) { thread_local char packet[1024]; long file_size = 0; read(mSocketId, &file_size, sizeof(long)); if(file_size == 0) return; cout << "size: " << file_size << endl; FILE *file; file = fopen(filepath.c_str(), "wb+"); int bytes_received = 0; int length; while (bytes_received < file_size) { //cout << "remains: " << remains << endl; int remains = file_size - bytes_received; int packetSize = sizeof(packet); if (remains < packetSize) { length = read(mSocketId, packet, remains); } else { length = read(mSocketId, packet, sizeof(packet)); } bytes_received += length; fwrite(packet, length, 1, file); } fclose(file); }
## Main.cc#include "ImageServer.h" #include <iostream> #include <unistd.h> int main() { std::cout << "Hello, World!" << std::endl; shared_ptr<ImageServer> server = make_shared<ImageServer>(); server->start(); while(true) { usleep(1000 * 1000); } server->stop(); return 0; }