最近我已经安装了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的向量。现在我只知道我一次发送一个字节。 问题是:
当我知道传输完成时(从客户端和服务器端)如何停止传输?
如何发送长度不同的数据,如果不知道将发送多少数据,该如何接收?这样,我认为我无法将所有数据保存到向量中,因此,如果缓冲区大小不断增加,应该如何将其存储在内存中?
我知道RTP用于实时传输(我打算在以后使用),但是现在我只想掌握网络的基本概念。