#include <gtest/gtest.h>
#ifdef _WIN32
#define INC_SRT_WIN_WINTIME
#endif
#include "srt.h"
#include <thread>
#include <fstream>
#include <ctime>
#include <vector>
TEST(Transmission, FileUpload)
{
srt_startup();
SRTSOCKET sock_lsn = srt_create_socket(), sock_clr = srt_create_socket();
int tt = SRTT_FILE;
srt_setsockflag(sock_lsn, SRTO_TRANSTYPE, &tt, sizeof tt);
srt_setsockflag(sock_clr, SRTO_TRANSTYPE, &tt, sizeof tt);
sockaddr_in sa_lsn = sockaddr_in();
sa_lsn.sin_family = AF_INET;
sa_lsn.sin_addr.s_addr = INADDR_ANY;
sa_lsn.sin_port = htons(5555);
srt_bind(sock_lsn, (sockaddr*)&sa_lsn, sizeof sa_lsn);
int optval = 0;
int optlen = sizeof optval;
ASSERT_EQ(srt_getsockflag(sock_lsn, SRTO_SNDBUF, &optval, &optlen), 0);
size_t filesize = 7 * optval;
{
std::cout << "WILL CREATE source file with size=" << filesize << " (= 7 * " << optval << "[sndbuf])\n";
std::ofstream outfile("file.source", std::ios::out | std::ios::binary);
ASSERT_EQ(!!outfile, true);
srand(time(0));
for (size_t i = 0; i < filesize; ++i)
{
char outbyte = rand() % 255;
outfile.write(&outbyte, 1);
}
}
srt_listen(sock_lsn, 1);
bool thread_exit = false;
auto client = std::thread([&]
{
sockaddr_in remote;
int len = sizeof remote;
const SRTSOCKET accepted_sock = srt_accept(sock_lsn, (sockaddr*)&remote, &len);
ASSERT_GT(accepted_sock, 0);
if (accepted_sock == SRT_INVALID_SOCK)
{
std::cerr << srt_getlasterror_str() << std::endl;
EXPECT_NE(srt_close(sock_lsn), SRT_ERROR);
return;
}
std::ofstream copyfile("file.target", std::ios::out | std::ios::trunc | std::ios::binary);
std::vector<char> buf(1456);
for (;;)
{
int n = srt_recv(accepted_sock, buf.data(), 1456);
ASSERT_NE(n, SRT_ERROR);
if (n == 0)
{
break;
}
copyfile.write(buf.data(), n);
}
EXPECT_NE(srt_close(accepted_sock), SRT_ERROR);
thread_exit = true;
});
sockaddr_in sa = sockaddr_in();
sa.sin_family = AF_INET;
sa.sin_port = htons(5555);
ASSERT_EQ(inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr), 1);
srt_connect(sock_clr, (sockaddr*)&sa, sizeof(sa));
std::cout << "Connection initialized" << std::endl;
std::ifstream ifile("file.source", std::ios::in | std::ios::binary);
std::vector<char> buf(1456);
for (;;)
{
size_t n = ifile.read(buf.data(), 1456).gcount();
size_t shift = 0;
while (n > 0)
{
int st = srt_send(sock_clr, buf.data()+shift, n);
ASSERT_GT(st, 0);
n -= st;
shift += st;
}
if (ifile.eof())
{
break;
}
ASSERT_EQ(ifile.good(), true);
}
std::cout << "Finished sending, closing sockets:\n";
srt_close(sock_clr);
srt_close(sock_lsn);
std::cout << "Sockets closed, joining receiver thread\n";
client.join();
std::ifstream tarfile("file.target");
EXPECT_EQ(!!tarfile, true);
tarfile.seekg(0, std::ios::end);
size_t tar_size = tarfile.tellg();
EXPECT_EQ(tar_size, filesize);
std::cout << "Comparing files\n";
tarfile.seekg(0, std::ios::end);
ifile.seekg(0, std::ios::beg);
for (size_t i = 0; i < tar_size; ++i)
{
EXPECT_EQ(ifile.get(), tarfile.get());
}
EXPECT_EQ(ifile.get(), EOF);
EXPECT_EQ(tarfile.get(), EOF);
remove("file.source");
remove("file.target");
(void)srt_cleanup();
}