В последнее время я установил jrtplib (C ++), и я пытаюсь понять, как я должен получать данные из пакетов, сохранять их в один буфер и в конце передачи сохранять все эти данные в файл.До сих пор я получил это (в основном из примеров файлов, поставляемых с библиотекой).Это сервер:
using namespace jrtplib;
int main(void)
{
#ifdef RTP_SOCKETTYPE_WINSOCK
WSADATA dat;
WSAStartup(MAKEWORD(2,2),&dat);
#endif // RTP_SOCKETTYPE_WINSOCK
RTPSession sess;
uint16_t portbase = 5000;
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
// IMPORTANT: The local timestamp unit MUST be set, otherwise
// RTCP Sender Report info will be calculated wrong
// In this case, we'll be sending 10 samples each second, so we'll
// put the timestamp unit to (1.0/10.0)
sessparams.SetOwnTimestampUnit(1.0/10.0);
sessparams.SetAcceptOwnPackets(true);
transparams.SetPortbase(portbase);
int status;
status = sess.Create(sessparams,&transparams);
checkerror(status);
bool done = false;
std::cout << "Waiting for some data...\n";
RTPTime startTime = RTPTime::CurrentTime();
std::vector<int8_t> data;
while(!done)
{
std::cout << "Waiting for some data...\n";
sess.BeginDataAccess();
// check incoming packets
if (sess.GotoFirstSourceWithData())
{
do
{
RTPPacket *pack;
while ((pack = sess.GetNextPacket()) != NULL)
{
// You can examine the data here
data.push_back(*(pack->GetPayloadData()));
// we don't longer need the packet, so
// we'll delete it
sess.DeletePacket(pack);
}
} while (sess.GotoNextSourceWithData());
}
sess.EndDataAccess();
#ifndef RTP_SUPPORT_THREAD
status = sess.Poll();
checkerror(status);
#endif // RTP_SUPPORT_THREAD
RTPTime::Wait(RTPTime(0.020));
RTPTime t = RTPTime::CurrentTime();
t -= startTime;
if ( t > RTPTime(100.0) ) {
done = true;
}
}
sess.BYEDestroy(RTPTime(10,0),0,0);
#ifdef RTP_SOCKETTYPE_WINSOCK
WSACleanup();
#endif // RTP_SOCKETTYPE_WINSOCK
FILE *file = fopen("d:/file.png", "w");
if (file == NULL){
printf("Could not open file for saving!\n");
exit(1);
}
for (int i = 0; i < data.size(); i++){
fwrite(&data[i], sizeof(data[i]), 1, file);
}
return 0;
}
А это клиент:
using namespace jrtplib;
int main()
{
#ifdef RTP_SOCKETTYPE_WINSOCK
WSADATA dat;
WSAStartup(MAKEWORD(2,2),&dat);
#endif
FILE *file = fopen("c:/file.png", "rb");
if (file == NULL){
printf("Could not open file!\n");
exit(1);
}
fseek(file, 0L, SEEK_END);
auto fsize = ftell(file);
fseek(file, 0L, SEEK_SET);
printf("File size: %ld\n", fsize);
auto *buffer = (unsigned char*) malloc(fsize);
fread(buffer, fsize, 1, file);
fclose(file);
file = NULL;
uint16_t portbase = 5000;
uint16_t destport = 5000;
std::string ipstr = "192.168.1.164";
uint32_t destip = inet_addr(ipstr.c_str());
if (destip == INADDR_NONE)
{
std::cerr << "Bad IP address specified" << std::endl;
return -1;
}
destip = ntohl(destip);
/* Parameters for the transmission component */
RTPUDPv4TransmissionParams transparams;
transparams.SetPortbase(portbase);
RTPSessionParams sessparams;
sessparams.SetOwnTimestampUnit(1.0/10.0);
sessparams.SetAcceptOwnPackets(true);
// Give general options for session
RTPSession sess;
int status = sess.Create(sessparams,&transparams);
checkerror(status);
sess.SetDefaultPayloadType(96);
sess.SetDefaultMark(false);
sess.SetDefaultTimestampIncrement(160);
/* Specify to which destinations rtp and rtcp data should be sent. */
RTPIPv4Address addr(destip,destport);
status = sess.AddDestination(addr);
checkerror(status);
RTPTime delay(0.020);
RTPTime starttime = RTPTime::CurrentTime();
int transmitted = 0;
auto *p = buffer;
bool done = false;
while(!done) {
// send the packet
status = sess.SendPacket(p, sizeof(*p));
checkerror(status);
transmitted += sizeof(*p);
p++;
RTPTime::Wait(delay);
RTPTime t = RTPTime::CurrentTime();
t -= starttime;
if (t > RTPTime(100.0)){
*buffer = 0;
status = sess.SendPacket(p, sizeof(*p));
transmitted += sizeof(*p);
done = true;
}
printf("\nSent %d bytes\n", transmitted);
}
sess.BYEDestroy(RTPTime(10,0),0,0);
#ifdef RTP_SOCKETTYPE_WINSOCK
WSACleanup();
#endif
return 0;
}
Мне удалось отправить небольшие текстовые файлы, но только если я знал точный размер файла -Я изменил сервер, чтобы он остановился на точном количестве полученных байтов, чтобы сделать это.Во-вторых, я всегда получаю 1 байт одновременно с 1-байтовым вектором: вектором int8_t.Пока я просто знаю, что посылаю 1 байт за раз.Вопросы:
Как остановить передачу, когда я знаю, что она завершена (со стороны клиента и сервера)?
Как сделатьЯ отправляю данные разной длины и как их получить, если я не знаю, сколько будет отправлено?Таким образом, я не думаю, что смогу сохранить все данные в векторе, поэтому как мне сохранить их в памяти, если размер буфера постоянно увеличивается?
Я знаю, что используется RTPдля передачи в режиме реального времени (которую я намерен использовать позже), но сейчас я просто хотел понять основные концепции сетей.