Member 13123405 Ответов: 2

Код, не работающий для универсального типа vector< T> В C++


Я пытаюсь отправить изображения на сервер. Раньше у меня была простая функция
void fileSend(const char* fpath)
Эта функция способна отправить один файл изображения на сервер. Но, я должен отправить много изображений на сервер сразу, поэтому я пошел на vector<t>. Я перегружал предыдущий метод с помощью
void fileSend(const vector<string>& fnames)
Но теперь программа резко останавливается, не посылая никаких изображений. Я пытался найти проблему, но не могу понять, что происходит. Он не работает
void fileSend(const vector<string>& fnames)
когда я вызываю перегруженный метод
fileSend(fnames[k].c_str());
Пожалуйста помочь

Что я уже пробовал:

void fileSend(const char *fpath)
	{
		// Extract only filename from given path.
		char filename[50];
		int i = strlen(fpath);
		for (; i > 0; i--)
		{
			if (fpath[i - 1] == '\\')
				break;
		}
		for (int j = 0; i <= (int)strlen(fpath); i++)
		{
			filename[j++] = fpath[i];
		}

		ifstream myFile(fpath, ios::in | ios::binary | ios::ate);
		int size = (int)myFile.tellg();
		myFile.close();

		char filesize[10]; itoa(size, filesize, 10);
		send(sock, filename, strlen(filename), 0);
		char rec[32] = ""; recv(sock, rec, 32, 0);

		send(sock, filesize, strlen(filesize), 0);
		recv(sock, rec, 32, 0);

		FILE *fr = fopen(fpath, "rb");

		while (size > 0)
		{
			char buffer[1030];

			if (size >= 1024)
			{
				fread(buffer, 1024, 1, fr);
				send(sock, buffer, 1024, 0);
				recv(sock, rec, 32, 0);
			}
			else
			{
				fread(buffer, size, 1, fr);
				buffer[size] = '\0';
				send(sock, buffer, size, 0);
				recv(sock, rec, 32, 0);
			}
			size -= 1024;
		}
		fclose(fr);
	}

	void fileSend(const vector<string>& fnames)
	{
		for (int k = 0; k < fnames.size(); k++)
		{
			fileSend(fnames[k].c_str()); // call the original function
		}
	}

Я вызываю эту функцию в main () как:
vector<string> filenames;
	string path = "C:\\Images:\\";
	string imageName;
	string fullPath;
	int numberOfImages;

	while (true)
	{
		cout << "Enter the number of images you want to send : ";
		cin >> numberOfImages;

		for (int i = 0; i < numberOfImages; i++)
		{
			cout << "Select an image:";
			cin >> imageName;
			fullPath = path + imageName;
			filenames.push_back(fullPath);
		}

		client.fileSend(filenames);
}

клиент-это объект класса Client, в котором я написал функции fileSend()

CPallini

Вы должны использовать отладчик, чтобы найти проблему.

Richard MacCutchan

Вчера я объяснил вам, что ваш цикл должен быть вокруг вектора и передавать каждое имя файла в функцию отправки по одному.

Member 13123405

@Richard я не понял

Richard MacCutchan

Вы создали вектор, содержащий список имен файлов. Все, что вам нужно сделать, это повторить этот вектор (создать цикл) и передать каждое имя файла функции, которая отправляет его на сервер.

2 Ответов

Рейтинг:
2

KarstenK

путь звука наблюдать странные:

string path = "C:\\Images:\\";
со вторым ":"

Решите эту проблему и отладьте код.Может быть, перегруженный вызов не разрешен так, как вы хотите. Попробуйте переименовать одну функцию.


Member 13123405

@KarstenK я убрал двоеточие с пути. Но, тем не менее, я сталкиваюсь с той же проблемой

Рейтинг:
2

Jochen Arndt

В вашем коде нет четкой концепции, и вы смешиваете библиотечные функции C и C++ для аналогичных задач (например, используя потоки C++ и C для файловых операций).

На самом деле я не вижу, где и почему ваш код терпит неудачу, но вот несколько советов:

Ваш код не проверяет наличие ошибок. Вы должны проверить возвращаемое значение каждой функции, которая может возвращать состояние ошибки и обрабатывать исключения (например, при открытии файла a с помощью ifstream потерпеть неудачу). При возникновении ошибок прерывайте выполнение и выводите сообщение об ошибке.

Получить указатель на имя файла для заданного полного пути довольно просто (ваш код слишком сложен, и нет необходимости в дополнительном буфере со строками const):

const char * filename = strrchr(fpath, '\\');
if (filename)
    filename++;
else
    filename = fpath;

Тогда вы отправляете две строки, но без конечного нуля. Как получатель должен знать, сколько байтов он должен прочитать?
Общим решением этой проблемы является отправка сначала размеров (в виде двоичных значений, а не строк), а затем содержимого. Такая реализация называется протоколом передачи и должна быть определена перед написанием любой строки кода. Обычно он реализуется путем определения структуры. В вашем случае это может выглядеть так:
#include <stdint.h>

struct myprotocol {
    uint32_t namelen;
    uint32_t filesize;
    char filename[1];
};
Его можно использовать как
uint8_t buf[sizeof(myprotocol) + MAX_FILE_NAME_LEN];
prot * myprotocol = static_cast<myprotocol*>(buf);
prot->namelen = strlen(filename);
prot->filesize = filesize;
strcpy(prot->filename, filename);
if (send(socket, buf, sizeof(myprotocol) + prot->namelen, 0) < 0)
{
    // Report error here
    return; // May also return error indicator or code (errno) here
}
// Now send image data
Приемник может использовать аналогичный буфер и читать sizeof(myprotocol) в этот буфер. Тогда он сможет читать namelen байты в соответствующем месте буфера с последующим считыванием данных изображения:
// Error checking omitted in this example!

// Receive the header
recv(socket, buf, sizeof(myprotocol), 0);
// Receive the remaining name characters (first already read above)
recv(socket, &prot->filename[1], prot->namelen, 0);
// Receive now prot->filesize image data bytes

Преимущество этого метода заключается в том, что получатель точно знает, сколько байтов было отправлено, и может предоставить или выделить буферы соответственно.

Если ваша программа все еще работает не так, как ожидалось (не показывая никаких сообщений об ошибках), вы должны запустить ее в отладчике.