C++语言实现,SRS流服务器、GPU推理服务器、本地App的三方端口的推流、取流和推理结果发送的代码,使用RTSP协议和socket、TCP协议
#include
#include
#include
#include
#include
#include
#include
#define MAX_BUFFER_SIZE 1024
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 4) {
cout << "Usage: " << argv[0] << " " << endl;
return 1;
}
const char *srs_server_ip = argv[1];
int srs_server_port = atoi(argv[2]);
const char *gpu_server_ip = argv[3];
// 创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return 1;
}
// 设置socket选项
int optval = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
perror("setsockopt");
return 1;
}
// 绑定socket
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(0);
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
return 1;
}
// 获取本地端口号
struct sockaddr_in local_addr;
socklen_t local_addr_len = sizeof(local_addr);
if (getsockname(sockfd, (struct sockaddr *)&local_addr, &local_addr_len) < 0) {
perror("getsockname");
return 1;
}
int local_port = ntohs(local_addr.sin_port);
// 监听socket
if (listen(sockfd, 5) < 0) {
perror("listen");
return 1;
}
// 连接SRS流服务器
int srs_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (srs_sockfd < 0) {
perror("socket");
return 1;
}
struct sockaddr_in srs_server_addr;
memset(&srs_server_addr, 0, sizeof(srs_server_addr));
srs_server_addr.sin_family = AF_INET;
srs_server_addr.sin_addr.s_addr = inet_addr(srs_server_ip);
srs_server_addr.sin_port = htons(srs_server_port);
if (connect(srs_sockfd, (struct sockaddr *)&srs_server_addr, sizeof(srs_server_addr)) < 0) {
perror("connect");
return 1;
}
// 发送RTSP SETUP请求
const char *setup_request = "SETUP rtsp://example.com/media.mp4 RTSP/1.0\r\n"
"CSeq: 1\r\n"
"Transport: RTP/AVP/TCP;unicast;interleaved=0-1\r\n"
"\r\n";
if (send(srs_sockfd, setup_request, strlen(setup_request), 0) < 0) {
perror("send");
return 1;
}
// 接收RTSP SETUP响应
char buffer[MAX_BUFFER_SIZE];
memset(buffer, 0, sizeof(buffer));
if (recv(srs_sockfd, buffer, sizeof(buffer), 0) < 0) {
perror("recv");
return 1;
}
cout << buffer << endl;
// 发送RTSP PLAY请求
const char *play_request = "PLAY rtsp://example.com/media.mp4 RTSP/1.0\r\n"
"CSeq: 2\r\n"
"Session: 1234567890\r\n"
"\r\n";
if (send(srs_sockfd, play_request, strlen(play_request), 0) < 0) {
perror("send");
return 1;
}
// 接收RTSP PLAY响应
memset(buffer, 0, sizeof(buffer));
if (recv(srs_sockfd, buffer, sizeof(buffer), 0) < 0) {
perror("recv");
return 1;
}
cout << buffer << endl;
// 接受客户端连接
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_sockfd < 0) {
perror("accept");
return 1;
}
// 连接GPU推理服务器
int gpu_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (gpu_sockfd < 0) {
perror("socket");
return 1;
}
struct sockaddr_in gpu_server_addr;
memset(&gpu_server_addr, 0, sizeof(gpu_server_addr));
gpu_server_addr.sin_family = AF_INET;
gpu_server_addr.sin_addr.s_addr = inet_addr(gpu_server_ip);
gpu_server_addr.sin_port = htons(12345);
if (connect(gpu_sockfd, (struct sockaddr *)&gpu_server_addr, sizeof(gpu_server_addr)) < 0) {
perror("connect");
return 1;
}
// 接收视频流数据并发送给GPU推理服务器
while (true) {
memset(buffer, 0, sizeof(buffer));
int n = recv(client_sockfd, buffer, sizeof(buffer), 0);
if (n < 0) {
perror("recv");
break;
} else if (n == 0) {
break;
} else {
// 发送视频流数据给GPU推理服务器
if (send(gpu_sockfd, buffer, n, 0) < 0) {
perror("send");
break;
}
// 接收GPU推理结果并发送给本地App
memset(buffer, 0, sizeof(buffer));
int m = recv(gpu_sockfd, buffer, sizeof(buffer), 0);
if (m < 0) {
perror("recv");
break;
} else if (m == 0) {
break;
} else {
// 发送GPU推理结果给本地App
if (send(client_sockfd, buffer, m, 0) < 0) {
perror("send");
break;
}
}
}
}
// 关闭socket
close(gpu_sockfd);
close(client_sockfd);
close(srs_sockfd);
close(sockfd);
return 0;
}