Как попросить сервер создать файл с определенным именем с клиентского конца в программировании MFC csocket?
- Привет! Я переношу файлы из папки серверного приложения в папку клиентского приложения один раз после установления соединения. Я даю имя файла для создания нового текстового файла в клиентской программе. Вместо этого я хочу, чтобы сервер отправлял любое сообщение или команду, чтобы попросить клиента создать новый текстовый файл с определенным именем.
Что я уже пробовал:
Это код в клиентском конце, где я даю имя файла для создания.
int br=SockConnection.Прием(бафф,1000);
То Cfile Его Доствили;
Его доствили.Open(L"Myreceivedfile", CFile::modeCreate | CFile::modeWrite);
Его доствили.Пиши (бафф,БР);
Вместо этого я хочу, чтобы сервер проинформировал клиента о создании файла с определенным именем. Пожалуйста, помогите. Спасибо.
Richard MacCutchan
Попросите сервер отправить имя файла в качестве первого сообщения.
rmds
Пожалуйста, поправьте меня, если я ошибаюсь. Вы хотите сказать, что это так?
-SockConnection.Send(L"Myinputfiledata", 0);"
Richard MacCutchan
Как бы. Но вы должны убедиться, что и клиент, и сервер понимают, о чем идет речь в каждом сообщении. Поэтому сообщение с именем файла должно содержать какой-то идентификатор, чтобы его не приняли за обычные данные. Вы должны разработать протокол между вашими терминалами, чтобы они могли проверять информацию, передаваемую между ними. Не думайте, что содержание сообщения-это то, что вы думаете, что оно должно быть.
rmds
Объяснение кристально ясно! Допустим, у меня есть несколько Receive() в клиентском приложении, и мне нужно отправить сообщение или данные с сервера. Как отправить сообщение конкретному Receive()? Я действительно погуглил примеры, но безуспешно. Пожалуйста, пролейте немного света на этот пример. Спасибо!
Richard MacCutchan
Я уже объяснил, что вам нужно сделать. Каждое сообщение должно содержать заголовок, определяющий его содержание. Итак, чтобы запустить новый файл, отправьте сообщение с заголовком и именем файла. Чтобы отправить некоторое содержимое файла, отправьте заголовок плюс некоторые данные. Заголовок должен содержать флаг, определяющий тип записи, и поле длины, сообщающее получателю, какой длины сообщение.
Rick York
Чтобы развить то, что написал Ричард, в предыдущем поколении моего приложения было несколько серверов, которые мы просили выполнять задачи, и они были связаны с сокетами. Каждое сообщение, отправленное им, имело заголовок, который имел несколько байтов версии, длину сообщения и команду. Команда указала серверу, что делать с данными сообщения. Одна команда сообщила серверу, что сообщение содержит копию приложения и ему необходимо обновить себя. Это был интересный маленький процесс. Во всяком случае, я рекомендую принять нечто подобное : включить заголовок в сообщение, чтобы сказать другой стороне, что делать с данными.
rmds
Я понимаю, но на самом деле я никогда этого не делал. Я пытаюсь со вчерашнего дня, но не могу найти, как выглядит send() с заголовком команды. Может ли по крайней мере показать мне проблеск send() с заголовком команды с любым примером? Большое спасибо.
Rick York
send принимает указатель на символьный буфер и длину, поэтому вам нужно собрать символьный буфер для отправки. Memcpy ваш заголовок в начало буфера и следуйте за ним с данными. Вы делаете обратное на другом конце. Memcpy запускает буфер в ваш заголовок, а затем данные следуют за заголовком. Вы знаете, насколько велик заголовок, поэтому вы знаете, где найти данные. Кроме того, вы можете использовать потоки, чтобы настроить его и распаковать на другом конце.
rmds
Пройдя через многое, я сделал вот что...
Сервер:
структура typedef{
char* filename[20];
}буфер данных;
Data_Buffer data_buffer;
буфер данных.filename[21] = "myinputfile";
int nRet = SockConnection.Send((void*)&data_buffer, sizeof(data_buffer));
Клиент:
структура typedef{
char* filename[21];
}буфер данных;
Data_Buffer data_buffer;
int nRet = SockConnection.Receive((void*)&data_buffer, sizeof(data_buffer));
То Cfile Его Доствили;
CString filename = (LPCTSTR)&data_buffer;
Его доствили.Open(filename, CFile::modeCreate | CFile::modeWrite);
Его доствили.Писать(через буфер, БР);
Я получаю имя файла как мусорные значения.. Что пошло не так?
Rick York
Ваши определения неверны. Вы не можете отправить указатель через сокет и предположить, что он действителен, и массив указателей тоже не будет работать. Мой заголовок содержит четыре байта версии, поле длины сообщения и поле команды. Вот и все. Все должно быть статическими данными без указателей. Длина сообщения важна, потому что если у вас есть более 1500 байт данных, они должны будут идти в нескольких пакетах, и длина скажет вам, сколько вам нужно получить.
rmds
Не могли бы вы дать мне представление о заголовке, на который вы ссылаетесь, с сообщением, длиной и командой. Просто хочу посмотреть, как это выглядит, чтобы получить идею для реализации. Спасибо
Rick York
typedef struct { size_t length; INT command; UCHAR version[4]; } MsgHeader;
rmds
Я действительно ценю ваше время для этого. Не могли бы вы пояснить, что именно вы подразумеваете под заголовком? :
typedef struct COMMAND_HEADER {
char* SET_FILE_NAME;
int data_size;
}
пожалуйста поправьте меня если я ошибаюсь
rmds
Спасибо вам, Рик и Ричард!