В настоящее время я работаю над парой SCTP-сервер-клиент для Linux, которая должна отправлять файлы по одному потоку. Это потому, что другие потоки будут использоваться для отправки команд, телеметрии и т. Д. Я использую QT Creator, если это вообще помогает. Это требование, что я использую SCTP для этого. На данный момент сервер и клиент работают как отдельные приложения через локальный порт.
Вот важные фрагменты кода. И клиент, и сервер работают в отдельных потоках от их соответствующих функций main (), что позволяет в будущем реализовывать дополнительный код.
/*
*Server (Sending side):
*/
std::ifstream inFile("/home/username/test.png", std::ios::binary);
char buf[MAX_BUFFER+1];
while(inFile.read((char *)buf,sizeof(buf)))
{
//Sends the current buffer over stream 3
snd_ret = sctp_sendmsg( goodSock, (void *)buf, (size_t)strlen(buf),
NULL, 0, 0, 0, 3, 0, 0 );
/*
* in another thread there is a loop that receives messages
* the client side sends a message whenever it receives
* this ensures the data was sent and waits before sending more.
*/
while(confirmHandshake == false){/*...*/}
//delays so I can view and compare console outputs for debugging
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
У меня также есть запись буферов, которые он читает, в отдельный png с использованием ofstream. Этот аспект работает по большей части; он не читает и не записывает весь файл, но сейчас это меньше всего меня беспокоит.
/*
* Client (Recieving Side)
*/
//creates a file if it isn't there
std::ofstream file("write.png");
//instantiates ofstream
std::ofstream ofs;
//opens the file using binary, I've tried it with "| std::ios::out" too
ofs.open ("write.png", std::ios::binary);
//tried different buffer sizes, same results, currently set at 512
char inBuffer[MAX_BUFFER+1];
while(error != -1){
memset(inBuffer, 0, MAX_BUFFER+1);
in = sctp_recvmsg( connSock, (void *)inBuffer
, sizeof(inBuffer), (struct sockaddr *)NULL, 0
, &sndrcvinfo, &flags);
if( in != -1 && sndrcvinfo.sinfo_stream == 3){
//writes the buffer to the file every time it recieves
//I've tried changing the pointers around,
//also tried using sizeof() instead of strlen()
//this changed the results, nothing worked so far
ofs.write((char *)&inBuffer, strlen(inBuffer));
//sends a handhake message (stored in s_buffer) to server
snd_ret = sctp_sendmsg( connSock, (void *)s_buffer
,(size_t)strlen(s_buffer)
,NULL, 0, 0, 0, 4, 0, 0 );
}
}
Проблема, с которой я сталкиваюсь, состоит в том, что полученные данные отличаются от отправленных данных. Отправленные данные, кажется, в порядке, потому что я могу записать этот буфер в файл без повреждения файла.
Когда я открываю png, записанный на стороне клиента, изображение не может быть отображено, были различные ошибки в зависимости от различных изменений, которые я сделал в моих попытках отладить это.
Я не уверен, где данные идут плохо, это через сокет или запись файла. Искаженные представления ASCII, которые я получаю, когда печатаю обе стороны в свои консоли, выглядят почти одинаково.
Я также хотел бы знать, есть ли лучшие решения для чтения и записи файла. Или разные типы данных для отправки данных (думаю, \ n может быть одной проблемой). Я подумал, потенциально пытаясь преобразовать файл в шестнадцатеричный для передачи и преобразования обратно в двоичный файл, если все остальное не удается. Однако я хочу попытаться заставить его работать только с двоичным кодом.
Еще одна вещь, которая меня интересует: возможно ли просто использовать функции send и recv для socket.h одновременно с sctp_sendmsg и sctp_recvmsg. Я предполагаю, что это просто повесит программу, но у меня мало опыта работы с протоколами сокетов.
Я открыт для любых других предложений. Пока это все еще использует SCTP с потоками.
Спасибо!
Задача ещё не решена.
Других решений пока нет …