Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.04.2018, 23:43   #1
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
Радость Не знаю как выстроить логику (клиент-сервер TCP)

Есть программа по инвертированию файлов из подкаталогов. Нужно сделать клиент-сервер на TCP: сервер получает от клиента список каталогов и инвертирует содержимое файлов и возвращает их клиенту который прислал запрос.
Я написал как будет происходить инвертирование:
Код:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <filesystem>
namespace fs = std::experimental::filesystem;
void reverseFile(fs::path pfile)
{
	std::fstream ifs(pfile, std::ios::in);
	if (ifs.is_open())
	{
		std::string str{ std::istreambuf_iterator<char>{ifs.rdbuf()},{} };
		std::reverse(str.begin(), str.end());
		std::cout << "Filename: " << pfile.filename() << std::endl
			<< "Reverve File: " << str << std::endl;
	}
	else
	{
		std::cerr << "Unable to open file(s): " << pfile << "  " << pfile / pfile.filename() << "\n\n";
	}
	ifs.close();
}
int main()
{
	try
	{
		fs::path pd1("C:\\Users\\Alex\\Videos\\dir1"); // каталог с исходными файлами
		
		for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
		{
			if (fs::is_regular_file(ib->path())) // инвертируем каждый файл 
			{
				reverseFile(ib->path());
			}
		}

	}
	catch (std::exception const& exc)
	{
		std::cerr << "Exception: " << exc.what() << std::endl;
	}
}
Пока сделал заготовку клиента и сервера на TCP, дальше не знаю как двигаться:
Клиент:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
	int sock;
	int ret;
	struct sockaddr_in addr;
	char msg1[100], msg2[100];

	sock = socket(AF_INET, SOCK_STREAM, 0);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(7777);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");

	ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr));

	if (ret == -1)
	{
		printf("error connect\n");
		return 1;
	}

	char const* msg = "hello_server!!!";

	ret = send(sock, msg, strlen(msg), 0);

	if (ret > 0)
	{
		ret = recv(sock, msg1, 100, 0);

		if (ret > 0)
		{
			msg1[ret] = 0;

			printf("server: %s\n", msg1);
		}
	}
	else
	{
		printf("server disconnected!\n");
	}

	close(sock);

	return 0;
}
Сервер:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
	int serv;
	int ret;
	struct sockaddr_in addr;
	char msg1[100], msg2[100];

	serv = socket(AF_INET, SOCK_STREAM, 0);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(7777);
	addr.sin_addr.s_addr = INADDR_ANY;

	ret = bind(serv, (struct sockaddr*)&addr, sizeof(addr));

	if (ret == -1)
	{
		printf("error bind\n");
		return 1;
	}

	listen(serv, 1);

	int client = accept(serv, NULL, NULL);

	ret = recv(client, msg1, 100, 0);

	if (ret > 0)
	{
		msg1[ret] = 0;

		printf("client(%d): %s\n", client, msg1);

		sprintf(msg2, "ECHO %s", msg1);

		send(client, msg2, strlen(msg2), 0);

		sleep(1);
	}
	else
	{
		printf("client disconnected!\n");
	}

	close(client);
	close(serv);

	return 0;
}
Не знаю как реализовать взаимодействие клиента и сервера, т.к. в первый раз делаю такое. Как я понял клиент должен отправить c помощью send путь директории на сервер, сервер получает путь командой recv, затем должен выполняться алгоритм реверсирования и отправлять send'om клиенту вывод. Вывод можно сделать просто строкой как я написал
Код:
std::cout << "Filename: " << pfile.filename() << std::endl
			<< "Reverve File: " << str << std::endl;
Как можно такое сделать и правильно ли я понял как делать?
Alexis_777 вне форума Ответить с цитированием
Старый 30.04.2018, 01:29   #2
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

При выполнении инвертирования сервер отправляет или клиент получает лишние символы. На Windows нормально всё было. На Linux появились кракозябры. Из-за чего это может быть?
Client:
Код:
//g++ client.cpp -o client -std=c++14 -lstdc++fs
#include <unistd.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
 
int main(int argc, char** argv)
{
 
    int sock;
    int ret;
    struct sockaddr_in addr;
 
    sock = socket(AF_INET, SOCK_STREAM, 0);
 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(7777);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
    ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
 
    if (ret == -1)
    {
        printf("Error connect\n");
        return 1;
    }
    printf("Client started!\n"); //Клиент запущен!
    printf("Enter the directory to be inverted by the server: "); //Введите директорию, которая будет инвертирована сервером
    char path[128];
    scanf("%s", path);
    ret = send(sock, path, strlen(path), 0);
    printf("The directory %s for inverting is sent to the server!\n", path); //Каталог path для инвертирования отправляется на сервер!
    
    char rF[255];
 
 
    if (ret > 0)
    {
        //Прочтём данные которые отправил сервер.
        printf("Read the data that the server sent.\n");
        recv(sock, rF, 255, 0);
 
        if (ret > 0)
        {
            rF[ret] = '\0';
            printf("The server sent inverted data: %s\n", rF); //Сервер отправил инвертированные данные
            printf("Data received. The client is closed!\n"); //Данные получены. Клиент закрыт.
        }
    }
    else
    {
        printf("Server disconnected!\n");
    }
 
    close(sock);
 
    return 0;
}
Server:
Код:
//gcc server.cpp -o server -std=c++14 -lstdc++fs
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <experimental/filesystem>
 
namespace fs = std::experimental::filesystem;
 
char rF[255]; // хранение инвертирования файлов
// функция ивертирования файлов
void reverseFile(fs::path pfile)
{
    std::fstream ifs(pfile, std::ios::in);
    if (ifs.is_open())
    {
        std::string str{ std::istreambuf_iterator<char>{ifs.rdbuf()},{} };
        std::reverse(str.begin(), str.end());
        strcpy(rF, str.c_str());
    }
    else
    {
        std::cerr << "Unable to open file(s): " << pfile << "  " << pfile / pfile.filename() << "\n\n";
    }
    ifs.close();
}
// функция рекурсивного ивертирования файлов в директории
void fullReverse(fs::path pd1)
{
    try
    {
        for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
        {
            if (fs::is_regular_file(ib->path())) // инвертируем каждый файл 
            {
                reverseFile(ib->path());
            }
        }
    }
    catch (std::exception const& exc)
    {
        std::cerr << "Exception: " << exc.what() << std::endl;
    }
}
 
 
 
int main(int argc, char** argv)
{
    int serv;
    int ret;
    struct sockaddr_in addr;
    char path[128];
 
    serv = socket(AF_INET, SOCK_STREAM, 0);
 
    addr.sin_family = AF_INET;
    addr.sin_port = htons(7777);
    addr.sin_addr.s_addr = INADDR_ANY;
 
    ret = bind(serv, (struct sockaddr*)&addr, sizeof(addr));
 
    if (ret == -1)
    {
        printf("Error bind!\n");
        return 1;
    }
 
    listen(serv, 1);
 
    printf("Server started!\nWaiting for a request from the client...\n"); //Сервер запущен! Ожидание запроса от клиента ...
 
    int client = accept(serv, NULL, NULL);
 
    ret = recv(client, path, 128, 0);
 
    if (ret > 0)
    {
        path[ret] = '\0';
        printf("The client sent a directory for inverting: %s\n", path); //Клиент отправил каталог для инвертирования: buf
        fs::path pd1(path); // каталог с исходными файлами
        fullReverse(pd1); // инвертируем файлы и сохраняем результат в rF
        printf("Inverting completed, sending data to the client!\n"); //Инвертирование завершено, отправка данных клиенту!
        send(client, rF, strlen(rF), 0);
        printf("Data sent. The server is closed!\n");  //Данные отправлены. Сервер закрыт
        sleep(1);
    }
    else
    {
        printf("client disconnected!\n");
    }
 
    close(client);
    close(serv);
 
    return 0;
}
Выполнение сервера
Цитата:
Server started!
Waiting for a request from the client...
The client sent a directory for inverting: /home/student/dre1
Inverting completed, sending data to the client!
Data sent. The server is closed!
Выполнение клиента
Цитата:
Client started!
Enter the directory to be inverted by the server: /home/student/dre1
The directory /home/student/dre1 for inverting is sent to the server!
Read the data that the server sent.
The server sent inverted data:
ytrewq��n��?s��wk
Data received. The client is closed!
Должно быть просто ytrewq
Alexis_777 вне форума Ответить с цитированием
Старый 30.04.2018, 08:07   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от Alexis_777 Посмотреть сообщение
std::string str{ std::istreambuf_iterator<char>{ifs. rdbuf()},{} };
А здесь кто будет ставить нолик в конце?
waleri вне форума Ответить с цитированием
Старый 30.04.2018, 13:31   #4
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Исправил ret = recv(sock, rF, 255, 0); на клиенте удалил нечаянно ret = перед recv когда с винды на линукс переносил
Alexis_777 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите, пожалуйста, переписать код приложения по TCP клиент-сервер в UDP клиент - сервер... KhNJu C/C++ Сетевое программирование 3 12.03.2017 23:43
курсовик, C++, TCP сервер-клиент borisetingof Фриланс 3 29.12.2015 22:47
TCP/IP клиент -сервер zhenya.ya C/C++ Сетевое программирование 10 05.03.2011 22:01
как создать TCP клиент, TCP сервер ? DreamMaster911 C/C++ Сетевое программирование 1 26.10.2010 15:05
простой сервер(клиент) TCP nntpaha Общие вопросы C/C++ 4 25.12.2007 19:02