I am writing a custom RTSP server over TCP in C++. Below is my code.
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8000);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
{
perror("bind");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
read(new_socket, buffer, 1024);
std::string request_message(data);
std::string request_type = request_message.substr(0, request_message.find(" "));
std::string response_data;
std::string sequence_number;
std::string sub_str;
if (request_type == "OPTIONS")
{
char current_date[200];
time_t tt = time(NULL);
strftime(current_date, sizeof current_date, "%a, %b %d %Y %H:%M:%S GMT", gmtime(&tt));
std::string current_date_str(current_date);
sub_str = request_message.substr(0, request_message.find("User-Agent:"));
sequence_number = sub_str.substr(sub_str.find("CSeq: ") + 6);
response_data = "RTSP/1.0 200 OK\r\nCSeq: " + sequence_number + "\r\nPublic: DESCRIBE, GET_PARAMETER, SETUP, SET_PARAMETER, PLAY, RECORD, PAUSE, TREADOWN\r\nServer: My Custom RSTP Server\r\nDate: " + current_date_str + "\r\n";
send(new_socket, response_data , response_data.size(), 0);
}
else if (request_type == "DESCRIBE")
{
sub_str = request_message.substr(0, request_message.find("User-Agent:"));
sequence_number = sub_str.substr(sub_str.find("CSeq: ") + 6);
std::string cnt = "v=0\r\no=- " + std::to_string(rand()) + " 1 IN IP4 my_ip_address\r\ns=\r\nt=0 0\r\nm=video 0 RTP/AVP 26\r\nc=IN IP4 0.0.0.0\r\n";
response_data = "RTSP/1.0 200 OK\r\nCSeq: " + sequence_number + "\r\nCache-control: no-cache\r\nContent-Type: application/sdp\r\nContent-Base: rtsp://my_ip_address:8000\r\nContent-length: " + std::to_string(cnt.size()) + "\r\n" + cnt;
send(new_socket, response_data , response_data.size(), 0);
}
else if (request_type == "SETUP")
{
char current_date2[200];
time_t tt2 = time(NULL);
strftime(current_date2, sizeof current_date2, "%a, %b %d %Y %H:%M:%S GMT", gmtime(&tt2));
std::string current_date_str2(current_date2);
std::string transport = request_message.substr(request_message.find("Transport:"));
transport = transport.substr(0, transport.find("\r\n"));
sub_str = request_message.substr(0, request_message.find("Transport:"));
sequence_number = sub_str.substr(sub_str.find("CSeq: ") + 6);
response_data = "RTSP/1.0 200 OK\r\nCSeq: " + sequence_number + "\r\n" + transport + ";server_port=8000-8001;ssrc=4b003a1e\r\nDate: " + current_date_str2 + "\r\nSession: 1185d20035702ca\r\n";
send(new_socket, response_data , response_data.size(), 0);
}
else if (request_type == "PLAY")
{
std::string transport = request_message.substr(request_message.find("User-Agent:"));
transport = transport.substr(0, transport.find("\r\n"));
sub_str = request_message.substr(0, request_message.find("User-Agent:"));
sequence_number = sub_str.substr(sub_str.find("CSeq: ") + 6);
response_data = "RTSP/1.0 200 OK\r\nCSeq: " + sequence_number + "\r\nSession: 1185d20035702ca\r\n";
send(new_socket, response_data , response_data.size(), 0);
for(;;)
{
sendFrameData();
}
}
}
I use VLC as the RTSP client to connect to the server via rtsp://my_ip_address:8000
and use Wireshark to analyze the communication. There is no error at all. As result, they did not communicate over RTSP. They only communicated over TCP. VLC did not send requests over RTSP e.g. OPTIONS
, DESCRIBE
, SETUP
or PLAY
but it sent these requests over TCP. So the server also did not send RTSP responses.
But the server did get the message body of the VLC requests OPTIONS
, DESCRIBE
and SETUP
.
What did I do wrong? I am not looking for a complete solution. A right direction is also thankful!