rmds Ответов: 1

Как отправить имя файла с сервера на клиент в программировании сокетов MFC


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

typedef enum {
    CREATE_FILE     =   0,
    SEND_FILE       =   10,
    FILE_SIZE       =   20,
}CommandList;

typedef struct {
    CommandList command;
    CString iDataBuffer;
} COMMAND_HEADER;

Server Code:
COMMAND_HEADER command_header; 
command_header.command = CREATE_FILE;
command_header.iDataBuffer = findfile.cFileName;
int nfRet = SockConnection.Send((char*)&command_header,
sizeof(command_header));

nfRet = SockConnection.Send(command_header.iDataBuffer,
sizeof(command_header.iDataBuffer));

Client code:
CString fname[50];
int nRet = SockConnection.Receive((char*)&hCommand_header, sizeof(hCommand_header));
nRet = SockConnection.Receive(fname, 50);<pre>

what am I doing wrong?

What I have tried:

here, fname receives like <bad ptr>garbage values. Please let me know if this not clear and I'll strive to make this right.

1 Ответов

Рейтинг:
10

CPallini

Цитата:
int nfRet = SockConnection.Send((char*)&command_header,
оператор sizeof(command_header));

nfRet = SockConnection.Отправить(command_header.iDataBuffer,
sizeof(command_header.iDataBuffer));

Вышеприведенные призывы не имеют смысла.
На моей системе
  • sizeof(command_header)=8
  • sizeof(command_header.iDataBuffer)=4

независимый на самом деле iDataBuffer длина строки.
Вы должны написать что-то похожее на

int nfRet = SockConnection.Send((char*)&command_header.command,
sizeof(command_header.command));// send the command
size_t iDataLen = command_header.iDataBuffer.GetLength() * sizeof(TCHAR);
nfRet = SockConnection.Send((char*)command_header.iDataBuffer.GetBuffer(),
iDataLen);
command_header.iDataBuffer.ReleaseBuffer();


rmds

Спасибо, это говорит о многом! Однако я попробовал выше, все еще получая клиент, не получающий имя файла. Вот мой код клиента:

COMMAND_HEADER hCommand_header;
Преобразование имени[50];
int nRet = SockConnection.Receive((char*)&hCommand_header, sizeof(hCommand_header));
переключатель(hCommand_header.команда) {
case CREATE_FILE: {
nRet = SockConnection.Receive((char*)&hCommand_header.iDataBuffer, 50); // вместо I
// также пробовал это:
nRet = SockConnection.Receive(fname, 50);
}
перерыв;
Спасибо!

rmds

Хорошо...вместо этого этот код читает имя файла, но вместе с мусорным значением:
int nRet = SockConnection.Receive((char*)&hCommand_header.command,
оператор sizeof(hCommand_header.команда));

переключатель(hCommand_header.команда) {
case CREATE_FILE: {
nRet = SockConnection.Receive((char*)hCommand_header.iDataBuffer.GetBuffer(), 50);
}
перерыв;

как избавиться от мусора и распаковать имя файла в CString?

rmds

Я понял. Это сработало! Большое спасибо!!!

CPallini

Добро пожаловать. Я полагаю, что вы послали длину строки, прежде чем ее фактическое содержание.

rmds

Я ненавижу беспокоить вас, но уже довольно давно проверяю... Создается txtfile с этим именем, однако вышеприведенный код аварийно завершает работу с диалоговым окном ошибки"обнаружено повреждение кучи: после нормального блока. "CRT обнаружил, что приложение записало в память конец буфера кучи". Он выходит из строя, когда я нажимаю F10 после "DestFile.Open" в следующем коде:

переключатель(hCommand_header.команда) {
case CREATE_FILE: {
nRet = SockConnection.Receive((char*)hCommand_header.iDataBuffer.GetBuffer(),50);
(hCommand_header.iDataBuffer.GetBuffer())[nRet] = '\0';
Его доствили.Открыть(hCommand_header.iDataBuffer, CFile::modeCreate | CFile::modeWrite);
}
hCommand_header.iDataBuffer.Метод releasebuffer();
перерыв;

CPallini

Попробуй
nRet = SockConnection.Receive((char*)hCommand_header.iDataBuffer.GetBuffer(50),50*sizeof(TCHAR));
hCommand_header.iDataBuffer.ReleaseBuffer(nRet/sizeof(TCHAR));
Его доствили.Открыть(hCommand_header.iDataBuffer, CFile::modeCreate | CFile::modeWrite);

и удалите свой вызов ReleaseBuffer ().

rmds

Не могли бы вы, пожалуйста, дать мне знать, как вы приходите с вычислением GetBuffer() и ReleaseBuffer()? Это чистый вдохновитель!!! и это сработало для команды CREATE_FILE. Но, когда я меняю команду на SEND_FILE, hCommand_header.iDataBuffer все еще имеет мусорные значения. Большое спасибо!

CPallini

Я думаю, вам лучше использовать простые буферы памяти вместо того, чтобы CStrings для связи с сокетом.

CPallini

оба GetBuffer и Метод releasebuffer возьмите количество персонажи в то время как функции сокета используют байты. Число байтов равно:

bytes = sizeof(TCHAR)*characters

Количество символов равно
characters = bytes /sizeof(TCHAR)

Где sizeof(TCHAR) равен 1 в сборках ANSI и 2 в сборках UNICODE.

rmds

Вот этот фрагмент:

СЕРВЕРНЫЙ:

command_header.command = SEND_FILE;
command_header.iDataBuffer = findfile.возвращается;
int nfRet = SockConnection.Send((char*)&command_header.command,
оператор sizeof(command_header.команда));
size_t iDataLen = command_header.iDataBuffer.GetLength() * sizeof(TCHAR);
nfRet = SockConnection.Send((char*)command_header.iDataBuffer.GetBuffer(),iDataLen);
переключатель(command_header.command) {
case SEND_FILE: {
То Cfile Файле;
Исходный файл.Открыть(Filepath, CFile::modeRead);
ULONGLONG dwLength = исходный файл.Метода getlength может служить метод();
command_header.DataBuffer = новый символ[(int)dwLength + 1];
UINT nActual = исходный файл.Читать(command_header.Буфер данных,dwLength);
command_header.DataBuffer[nActual] = 0;
nfRet = SockConnection.Отправить(command_header.DataBuffer, nActual);

КЛИЕНТСКИЙ:
COMMAND_HEADER hCommand_header;
То Cfile Его Доствили;
char nBuf[1000];
int nRet = SockConnection.Receive((char*)&hCommand_header.command,
оператор sizeof(hCommand_header.команда));
nRet = SockConnection.Receive((char*)hCommand_header.iDataBuffer.GetBuffer(50),
50*sizeof(TCHAR));
hCommand_header.iDataBuffer.ReleaseBuffer(nRet/sizeof(TCHAR));

здесь: hCommand_header.в iDataBuffer все еще есть мусор, которого не было в команде CREATE_FILE.