基于RTSP的实现多媒体文件的下载
项目描述:嵌入式网络编程实训项目,独立完成基于RTSP的实现多媒体文件的下载;从指定的RTSP服务器(可使用live555)下载多媒体文件(文件格式为TS),需要将RTSP服务器返回的RTP数据包解析出来存成文件,存成的文件可以使用VLC播放器正常播放;熟悉网络编程异步通讯、RTSP协议交互、RTP协议包的格式。
项目代码地址:
1 /* 2 *时间:2013年3月27日 3 *目的:rtsp客户端测试程序 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <unistd.h> 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <sys/stat.h> 15 #include <netinet/in.h> 16 #include <arpa/inet.h> 17 18 #define BUFFERSIZE 4096 19 20 char *filename_buf,*ip_buf; 21 22 int creat_udp(int i, int port); 23 int recv_data_from_server(int sock_udp_fd1,int sock_udp_fd2); 24 25 int main(int argc, char *argv[]) 26 { 27 int i = 0, j = 0, k = 0, m = 0; 28 int sock_fd,inet_pton_fd,connect_fd,send_fd,recv_fd,sock_udp_fd1,sock_udp_fd2; 29 char *p, *q, buf[BUFFERSIZE],rec_buf[BUFFERSIZE],session[BUFFERSIZE]; 30 struct sockaddr_in ser_addr; 31 32 p = argv[1]; 33 ip_buf = (char *)malloc(20); 34 filename_buf = (char *)malloc(20); 35 memset(ip_buf, '\0', 20); 36 memset(filename_buf, '\0', 20); 37 38 while (1) 39 { 40 if (p[i] <= '9' && p[i] >= '0') 41 { 42 ip_buf[k] = p[i]; 43 k++; 44 } 45 if (p[i] == '.') 46 { 47 ip_buf[k] = p[i]; 48 k++; 49 j++; 50 } 51 i++; 52 if (3 == j) 53 { 54 if ((p[i] < '0') || (p[i] > '9')) 55 break; 56 } 57 58 memcpy(filename_buf,argv[1] + strlen(ip_buf) + 9, strlen(argv[1] + strlen(ip_buf))); 59 } 60 61 printf("ip = %s\n",ip_buf); 62 printf("filename = %s\n",filename_buf); 63 64 sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 65 if (sock_fd < 0) 66 { 67 printf("TCP socket() fail.\n"); 68 exit(1); 69 } 70 printf("TCP socket() success.\n"); 71 printf("sock_fd = %d\n",sock_fd); 72 73 memset(&ser_addr,0,sizeof(ser_addr)); 74 ser_addr.sin_family = AF_INET; 75 76 inet_pton_fd = inet_pton(AF_INET, ip_buf, &ser_addr.sin_addr); 77 if (inet_pton_fd < 0) 78 { 79 printf("TCP inet_pton() fail.\n"); 80 exit(1); 81 } 82 printf("TCP inet_pton() success.\n"); 83 printf("inet_pton_fd = %d\n",inet_pton_fd); 84 85 ser_addr.sin_port = htons(554); 86 87 connect_fd = connect(sock_fd,(struct sockaddr *)&ser_addr,sizeof(ser_addr)); 88 if (connect_fd < 0) 89 { 90 printf("TCP connect() fail.\n"); 91 exit(1); 92 } 93 printf("TCP connect() success.\n"); 94 printf("connect_fd = %d\n",connect_fd); 95 96 memset(buf, 0, BUFFERSIZE); 97 98 printf("*********\n"); 99 sprintf(buf, "OPTIONS %s RTSP/1.0\r\n" 100 "CSeq:1\r\n" 101 "User-Agent:VLC media player(LIVE555 Streaming Media library version 2012.12.09)" 102 "\r\n" 103 "\r\n",argv[1]); 104 printf("send to server %s\n", buf); 105 106 send_fd = send(sock_fd, buf, strlen(buf), 0); 107 if (send_fd < 0) 108 { 109 printf("send() fail.\n"); 110 exit(1); 111 } 112 printf("send() success.\n"); 113 printf("send_fd = %d\n",send_fd); 114 115 memset(rec_buf, 0, BUFFERSIZE); 116 117 recv_fd = recv(sock_fd, rec_buf, sizeof(buf), 0); 118 if (recv_fd < 0) 119 { 120 printf("recv() fail.\n"); 121 exit(1); 122 } 123 printf("recv() success.\n"); 124 printf("recv_fd = %d\n",recv_fd); 125 printf("options recv from server is %s\n",rec_buf); 126 127 memset(buf, 0, BUFFERSIZE); 128 129 sprintf(buf, "DESCRIBE %s RTSP/1.0\r\n" 130 "CSeq:2\r\n" 131 "User-Agent:VLC media player(LIVE555 Streaming Media library version 2012.12.09)" 132 "\r\n" 133 "\r\n",argv[1]); 134 printf("send to server %s\n", buf); 135 136 send_fd = send(sock_fd, buf, strlen(buf), 0); 137 if (send_fd < 0) 138 { 139 printf("send() fail.\n"); 140 exit(1); 141 } 142 printf("send() success.\n"); 143 printf("send_fd = %d\n",send_fd); 144 145 memset(rec_buf, 0, BUFFERSIZE); 146 147 recv_fd = recv(sock_fd, rec_buf, sizeof(buf), 0); 148 if (recv_fd < 0) 149 { 150 printf("recv() fail.\n"); 151 exit(1); 152 } 153 printf("recv() success.\n"); 154 printf("recv_fd = %d\n",recv_fd); 155 printf("describe recv from server is %s\n",rec_buf); 156 157 sock_udp_fd1 = creat_udp(1, 5554); 158 sock_udp_fd2 = creat_udp(2, 5555); 159 160 memset(buf, 0, BUFFERSIZE); 161 162 sprintf(buf, "SETUP %s RTSP/1.0\r\n" 163 "CSeq:3\r\n" 164 "Transport: RTP/AVP;unicast;client_port=5554-5555" 165 "User-Agent:VLC media player(LIVE555 Streaming Media library version 2012.12.09)" 166 "\r\n" 167 "\r\n",argv[1]); 168 printf("send to server %s\n", buf); 169 170 send_fd = send(sock_fd, buf, strlen(buf), 0); 171 if (send_fd < 0) 172 { 173 printf("send() fail.\n"); 174 exit(1); 175 } 176 printf("send() success.\n"); 177 printf("send_fd = %d\n",send_fd); 178 179 memset(rec_buf, 0, BUFFERSIZE); 180 181 recv_fd = recv(sock_fd, rec_buf, sizeof(buf), 0); 182 if (recv_fd < 0) 183 { 184 printf("recv() fail.\n"); 185 exit(1); 186 } 187 printf("recv() success.\n"); 188 printf("recv_fd = %d\n",recv_fd); 189 printf("setup recv from server is %s\n",rec_buf); 190 191 memset(session, 0, BUFFERSIZE); 192 if (NULL == rec_buf) 193 { 194 printf("session fail.\n"); 195 exit(1); 196 } 197 q = strstr(rec_buf, "Session:"); 198 printf("q = %s\n",q); 199 while (*(q + 9 + m) != ('\0' && '\n' && '\r')) 200 { 201 session[m] = *(q +9 + m); 202 m++; 203 } 204 session[m] = '\0'; 205 printf("Session success and it is %s\n",session); 206 207 memset(buf, 0, BUFFERSIZE); 208 sprintf(buf, "PLAY %s RTSP/1.0\r\n" 209 "CSeq:4\r\n" 210 "Session: %s\r\n" 211 "Range:npt=0.000\r\n" 212 "User-Agent:VLC media player(LIVE555 Streaming Media library version 2012.12.09)" 213 "\r\n" 214 "\r\n",argv[1],session); 215 printf("send to server %s\n", buf); 216 217 send_fd = send(sock_fd, buf, strlen(buf), 0); 218 if (send_fd < 0) 219 { 220 printf("send() fail.\n"); 221 exit(1); 222 } 223 printf("send() success.\n"); 224 printf("send_fd = %d\n",send_fd); 225 226 memset(rec_buf, 0, BUFFERSIZE); 227 228 recv_fd = recv(sock_fd, rec_buf, sizeof(buf), 0); 229 if (recv_fd < 0) 230 { 231 printf("recv() fail.\n"); 232 exit(1); 233 } 234 printf("recv() success.\n"); 235 printf("recv_fd = %d\n",recv_fd); 236 printf("play recv from server is %s\n",rec_buf); 237 238 recv_data_from_server(sock_udp_fd1,sock_udp_fd2); 239 240 close(sock_fd); 241 return 0; 242 } 243 244 int creat_udp(int i, int port) 245 { 246 struct sockaddr_in udp_addr; 247 int sock_udp_fd,bind_udp_fd; 248 249 sock_udp_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 250 if (sock_udp_fd < 0) 251 { 252 printf("UDP socket() fail.\n"); 253 exit(1); 254 } 255 printf("UDP socket() success.\n"); 256 printf("sock_udp_fd = %d\n",sock_udp_fd); 257 258 memset(&udp_addr, 0, sizeof(udp_addr)); 259 udp_addr.sin_family = AF_INET; 260 udp_addr.sin_addr.s_addr = htonl(INADDR_ANY); 261 udp_addr.sin_port = htons(port); 262 263 bind_udp_fd = bind(sock_udp_fd,(struct sockaddr *)&udp_addr,sizeof(udp_addr)); 264 if (bind_udp_fd < 0) 265 { 266 printf("UDP bind() fail.\n"); 267 exit(1); 268 } 269 printf("UDP bind() success.\n"); 270 printf("bind_udp_fd = %d\n",bind_udp_fd); 271 272 printf("create UDP port%d success.\n",i); 273 printf("sock_udp_fd%d = %d\n",i,sock_udp_fd); 274 275 return sock_udp_fd; 276 } 277 278 int recv_data_from_server(int sock_udp_fd1, int sock_udp_fd2) 279 { 280 char recv_buf[BUFFERSIZE]; 281 int maxfd,filelen,fd,select_ret; 282 struct timeval tm; 283 fd_set read_fd; 284 285 if (sock_udp_fd1 >= sock_udp_fd2) 286 maxfd = sock_udp_fd1; 287 else 288 maxfd = sock_udp_fd2; 289 290 fd = open(filename_buf, O_CREAT | O_RDWR, 0666); 291 if (fd < 0) 292 { 293 printf("open %s fail.\n",filename_buf); 294 exit(1); 295 } 296 297 while (1) 298 { 299 tm.tv_sec = 5; 300 tm.tv_usec = 0; 301 302 FD_ZERO(&read_fd); 303 FD_SET(sock_udp_fd1,&read_fd); 304 FD_SET(sock_udp_fd2,&read_fd); 305 306 select_ret = select(maxfd + 1, &read_fd, NULL, NULL, &tm); 307 if (select_ret < 0) 308 { 309 perror("not readly file.\n"); 310 continue; 311 } 312 else if (0 == select_ret) 313 { 314 printf("time out\n"); 315 continue; 316 } 317 else 318 { 319 if (FD_ISSET(sock_udp_fd1,&read_fd)) 320 { 321 memset(recv_buf, 0, BUFFERSIZE); 322 filelen = recv(sock_udp_fd1,recv_buf,sizeof(recv_buf),0); 323 printf("sizeof recv_buf is %d.\n",sizeof(recv_buf)); 324 printf("1recv data size from server:%d\n",filelen); 325 326 if (filelen < 12) 327 { 328 printf("1recv data error.\n"); 329 continue; 330 } 331 filelen = filelen - 12; 332 write(fd,(recv_buf + 12),filelen); 333 } 334 if (FD_ISSET(sock_udp_fd2,&read_fd)) 335 { 336 memset(recv_buf, 0, BUFFERSIZE); 337 filelen = recv(sock_udp_fd2,recv_buf,sizeof(recv_buf),0); 338 printf("sizeof recv_buf is %d.\n",sizeof(recv_buf)); 339 printf("2recv data size from server:%d\n",filelen); 340 341 if (filelen < 12) 342 { 343 printf("2recv data error.\n"); 344 continue; 345 } 346 filelen = filelen - 12; 347 write(fd,(recv_buf + 12),filelen); 348 } 349 } 350 } 351 352 close(fd); 353 printf("file recv complete!\n"); 354 return 0; 355 }