C++使用socket传输图片

时间:2024-03-11 19:40:18

Client:

#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable: 4996)
#define Port 6000

SOCKET Socket, Sub;
WSADATA Winsock;
sockaddr_in Addr;
sockaddr_in IncomingAddress;
int AddressLen = sizeof(IncomingAddress);

BOOL send_function(BYTE* dib, int dib_size) {

    WSAStartup(MAKEWORD(2, 2), &Winsock);    // Start Winsock

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2)    // Check version
    {
        WSACleanup();
        return 0;
    }

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    ZeroMemory(&Addr, sizeof(Addr));
    Addr.sin_family = AF_INET;
    Addr.sin_port = htons(Port);
    bind(Socket, (sockaddr*)&Addr, sizeof(Addr));

    if (listen(Socket, 1) == SOCKET_ERROR)
    {
        printf("listening error\n");
    }
    else
    {
        printf("listening ok\n");
    }

    if (Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
    {
        char* ClientIP = inet_ntoa(IncomingAddress.sin_addr);
        int ClientPort = ntohs(IncomingAddress.sin_port);
        printf("Client conncted!\n");
        printf("IP: %s:%d\n", ClientIP, ClientPort);

        printf("Sending data .. \n");

        char bufsize[10];
        sprintf(bufsize, "%d", dib_size);

        send(Sub, (char*)bufsize, 10, 0);
        send(Sub, (char*)dib, dib_size, 0);


        closesocket(Sub);
        closesocket(Socket);
        WSACleanup();
    }
}


int main()
{
    //HWND hwnd = GetWindow(GetForegroundWindow(), GW_HWNDLAST);
    //RECT rc;
    //GetWindowRect(hwnd, &rc);
    //HDC hdcScreen = GetDC(NULL);
    //HDC hdc = CreateCompatibleDC(hdcScreen);
    //HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen,
    //rc.right - rc.left, rc.bottom - rc.top);
        //SelectObject(hdc, hbmp);
    //Print to memory hdc
    //PrintWindow(hwnd, hdc, NULL);
    HBITMAP Bitmap = (HBITMAP)LoadImage(NULL,
        "panda.bmp",  // file containing bitmap
        IMAGE_BITMAP,  // type = bitmap
        0, 0,      // original size
        LR_LOADFROMFILE);
    auto hcopy = (HBITMAP)CopyImage(Bitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);

    BITMAP bm;
    GetObject(hcopy, sizeof(bm), &bm);

    BITMAPINFOHEADER bi = { sizeof(bi) };
    bi.biWidth = bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biBitCount = bm.bmBitsPixel;
    bi.biPlanes = bm.bmPlanes;
    bi.biSizeImage = bm.bmWidthBytes * bm.bmHeight;

    LONG lineSize = bi.biWidth * bi.biBitCount / 8;
    BYTE* pLineData = new BYTE[lineSize];
    BYTE* pStart;
    BYTE* pEnd;
    BYTE* pData = (BYTE*)bm.bmBits;
    LONG lineStart = 0;
    LONG lineEnd = bi.biHeight - 1;
    while (lineStart < lineEnd)
    {
        pStart = pData + (lineStart * lineSize);
        pEnd = pData + (lineEnd * lineSize);
        // Swap the top with the bottom
        memcpy(pLineData, pStart, lineSize);
        memcpy(pStart, pEnd, lineSize);
        memcpy(pEnd, pLineData, lineSize);
        // Adjust the line index
        lineStart++;
        lineEnd--;
    }    

    int dib_size = sizeof(bi) + bi.biSizeImage;
    memcpy(pData, &bi, sizeof(bi));
    send_function(pData, dib_size);

    //cleanup
    DeleteObject(hcopy);
    delete pLineData;
    getchar();
    return 0;
}

Server:

#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable: 4996)


SOCKET Socket;
WSADATA Winsock;
sockaddr_in Addr;
int Addrlen = sizeof(Addr);
HBITMAP hbitmap;



int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  num = 0;          // number of image encoders
    UINT  size = 0;         // size of the image encoder array in bytes

    ImageCodecInfo* pImageCodecInfo = NULL;

    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return -1;  // Failure

    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
        return -1;  // Failure

    GetImageEncoders(num, size, pImageCodecInfo);

    for (UINT j = 0; j < num; ++j)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return 0;  // Success
        }
    }
    free(pImageCodecInfo);
    return -1;  // Failure
}

void receive_function(BYTE* dib, int dib_size)
{
    BITMAPINFOHEADER* bi = (BITMAPINFOHEADER*)dib;
    BYTE* bits = dib + sizeof(bi);
    hbitmap = CreateBitmap(bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, bits);


    /*OpenClipboard(NULL);
    EmptyClipboard();
    SetClipboardData(CF_BITMAP, hbitmap);
    CloseClipboard();
    printf("Clipboard set!");*/
}


int main()
{
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    WSAStartup(MAKEWORD(2, 2), &Winsock);    // Start Winsock

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2)    // Check version
    {
        WSACleanup();
        return 0;
    }

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    ZeroMemory(&Addr, sizeof(Addr));    // clear the struct
    Addr.sin_family = AF_INET;    // set the address family
    Addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    Addr.sin_port = htons(6000);    // set the port

    if (connect(Socket, (sockaddr*)&Addr, sizeof(Addr)) < 0)
    {
        printf("Connection failed !\n");
        getchar();
        return 0;
    }

    printf("Connection successful !\n");

    printf("Receiving data .. \n");

    int dib_size = 0;
    char Filesize[10];

    if (recv(Socket, Filesize, 10, 0)) // File size
    {
        dib_size = atoi(Filesize);
    }
    printf("File size: %d\n", dib_size);

    BYTE* dib = new BYTE[dib_size];
    if (recv(Socket, (char*)dib, dib_size, 0))
    {
        receive_function(dib, dib_size);
    }
    CLSID myClsId;
    int retVal = GetEncoderClsid(L"image/bmp", &myClsId);
    Bitmap *image = new Bitmap(hbitmap, NULL);
    image->Save(L"output.bmp", &myClsId, NULL);
    delete image;

    GdiplusShutdown(gdiplusToken);

    getchar();
    return 0;
}