Код сервера:
// ServerOne.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")
#include <fstream>
#include <algorithm>
#include <string>
#include <iterator>
void error(const char* msg)
{
//perror(msg);
std::cout<<'\n'<<WSAGetLastError();
WSACleanup();
std::cin.ignore();
exit(1);
}
void bzero(char*buf, int l)
{
for (int i = 0; i < l; i++)
buf[i] = '\0';
}
struct arg_s
{
char* buffer;
unsigned char* buffer2;
bool exit;
};
struct arg_sa
{
struct arg_s* lalk;
int current;
};
#define type struct arg_sa
int sockfd, * newsockfd;
int buflen2 = 4096;
struct sockaddr_in *cli_addr;
int* clilen;
int currentclient;
void session_(LPVOID args)
{
int current = currentclient++;
bzero((char*)&(cli_addr[current]), sizeof(&(cli_addr[current])));
newsockfd[current] = accept(sockfd, (struct sockaddr*)&(cli_addr[current]), &(clilen[current]));
if (newsockfd[current] < 0)
{
error("Error on accept\n");
}
// Определение контекстов
HDC ScreenDC = GetDC(0);
HDC MemoryDC = CreateCompatibleDC(ScreenDC);
// Фиксация размеров экрана
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
ScreenWidth = ((ScreenWidth - 1) / 4 + 1) * 4;
// Создание и частичное заполнение структуры формата
BITMAPINFO BMI;
BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BMI.bmiHeader.biWidth = ScreenWidth;
BMI.bmiHeader.biHeight = ScreenHeight; // Отрицательное значение высоты, чтобы изображение не было перевёрнутым
BMI.bmiHeader.biSizeImage = ScreenWidth * ScreenHeight * 3; // Ширина * Высота * Количество_цветов_на_пиксель
BMI.bmiHeader.biCompression = BI_RGB;
BMI.bmiHeader.biBitCount = 24;
BMI.bmiHeader.biPlanes = 1;
DWORD ScreenshotSize;
ScreenshotSize = BMI.bmiHeader.biSizeImage; // ScreenshotSize - глобальная переменная типа int, может меняться в ходе выполнения программы
unsigned char* ImageBuffer; // Указатель на блок данных BGR, управляемый HBITMAP (да, именно BGR - не RGB)
HBITMAP hBitmap = CreateDIBSection(ScreenDC, &BMI, DIB_RGB_COLORS, (void**)&ImageBuffer, 0, 0);
SelectObject(MemoryDC, hBitmap);
BitBlt(MemoryDC, 0, 0, ScreenWidth, ScreenHeight, ScreenDC, 0, 0, SRCCOPY);
// Контексты больше не нужны
DeleteDC(MemoryDC);
ReleaseDC(NULL, ScreenDC);
FILE* sFile = 0; // Дескриптор файла
// Обьявляем переменные, которые понадобятся нам в дальнейшем:
unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned char header[6];
unsigned char tempColors = 0;
// Открываем файл скриншота
fopen_s(&sFile,"Screen.tga", "wb");
// Проверяем, правильно ли произошло открытие
if (!sFile) {
}
// Записываем ширину и высоту:
header[0] = ScreenWidth % 256;
header[1] = ScreenWidth / 256;
header[2] = ScreenHeight % 256;
header[3] = ScreenHeight / 256;
header[4] = BMI.bmiHeader.biBitCount;
header[5] = 0;
// Записываем хидеры в начало файла:
fwrite(tgaHeader,1, sizeof(tgaHeader), sFile);
fwrite(header, sizeof(header), 1, sFile);
fwrite(ImageBuffer, BMI.bmiHeader.biSizeImage, 1, sFile);
// Закрываем файл
fclose(sFile);
FILE* f;
int n;
fopen_s(&f, "Screen.tga", "rb");
size_t bytes;
if (f != NULL)
{
while (1)
{
bytes = fread((char*)((type*)args)[current].lalk->buffer, sizeof(char), buflen2, f);
if (bytes <= 0)
break;
n = send(newsockfd[current], ((type*)args)[current].lalk->buffer, buflen2, 0);
}
fclose(f);
std::cout << "closing";
}
//Используем ImageBuffer как нам хочется... после удаляем его хендлер (HBITMAP) для избежания утечки памяти
DeleteObject(hBitmap);
}
int main()
{
WSADATA ws = { 0 };
if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
{
currentclient = 0;
int maxclients = 1;
cli_addr = new struct sockaddr_in[maxclients];
clilen = new int[maxclients];
for (int i = 0; i < maxclients; i++)
{
clilen[i] = sizeof(cli_addr[i]);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
struct sockaddr_in serv_addr;
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
int port = 30000;
serv_addr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
if (listen(sockfd, 10) < 0)
error("ERROR listen");
HANDLE* thread;
struct arg_sa* args;
while (true)
{
newsockfd = new int[maxclients];
thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);
args = new struct arg_sa[maxclients];
for (int i = 0; i < maxclients; i++)
{
args[i].lalk = new struct arg_s();
args[i].lalk->buffer = new char[buflen2];
args[i].lalk->buffer2 = new unsigned char[buflen2];
}
int i = -1;
while (++i < maxclients)
{
Sleep(1);
args[i].current = i;
args[i].lalk->exit = false;
thread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(session_), args, 0, 0);
}
for (int i = 0; i < maxclients; i++)
WaitForSingleObject(thread[i], INFINITE);
i = -1;
while (++i < maxclients)
{
shutdown(newsockfd[i], 0);
TerminateThread(thread[i], 0);
}
//delete[] newsockfd;
//free(thread);
currentclient = 0;
for (int i = 0; i < maxclients; i++)
{
//delete args[i].lalk;
//delete[] args[i].lalk->buffer;
}
//delete[] args;
}
shutdown(sockfd, 0);
WSACleanup();
return 0;
}
std::cin.ignore();
}
Код клиента:
// ClientOne.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <WinSock.h>
#pragma comment (lib,"WS2_32.lib")
void error(const char* msg)
{
//perror(msg);
std::cout << '\n' << WSAGetLastError();
WSACleanup();
std::cin.ignore();
exit(1);
}
void bzero(char* buf, int l)
{
for (int i = 0; i < l; i++)
buf[i] = '\0';
}
int main()
{
WSADATA ws = { 0 };
if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)
{
int sockfd;
struct hostent* server = gethostbyname("localhost");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
struct sockaddr_in serv_addr, cli_addr;
bzero((char*)&serv_addr, sizeof(serv_addr));
bzero((char*)&cli_addr, sizeof(cli_addr));
serv_addr.sin_family = AF_INET;
const char* address = "127.0.0.1";
serv_addr.sin_addr.s_addr = inet_addr(address);
int port = 30000;
serv_addr.sin_port = htons(port);
int servlen = sizeof(serv_addr);
int n = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);
if (n < 0)
{
error("ERROR on connect");
}
unsigned int buflen2 = 4096;
char* buffer = new char[buflen2];
FILE* f;
fopen_s(&f, "Screen.tga", "wb");
if (f != NULL)
{
while (1)
{
n = recv(sockfd, buffer, buflen2, 0);
if (n <= 0)
break;
fwrite(buffer, sizeof(char), buflen2, f);
}
fclose(f);
}
system("Screen.tga");
shutdown(sockfd, 0);
WSACleanup();
delete[] buffer;
return 0;
}
std::cin.ignore();
}