⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtsp_comm.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
 * 
 * Contributor(s): 
 *              Bill May        wmay@cisco.com
 */
/*
 * rtsp_comm.c - contains communication routines.
 */
#include "rtsp_private.h"

#ifdef HAVE_POLL
#include <sys/poll.h>
#endif

#if !defined(HAVE_ST_ADDRINFO) && !defined(_WIN32)
#include "addrinfo.h"
#endif

/*
 * rtsp_create_socket()
 * creates and connects socket to server.  Requires rtsp_info_t fields
 * port, server_addr, server_name be set.
 * returns 0 for success, -1 for failure
 */
static int rtsp_get_server_address (rtsp_client_t *info)
{
#ifdef HAVE_IPv6
  struct addrinfo hints;
  char port[32];
  int error;
  
  snprintf(port, sizeof(port), "%d", info->port);
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = PF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  error = getaddrinfo(info->server_name, port, &hints, &info->addr_info);
  if (error) {
    rtsp_debug(LOG_CRIT, "Can't get server address info %s - error %d", 
	       info->server_name, h_errno);
    return h_errno;
  }
#else
  struct hostent *host;
#if defined(_WIN32) || !defined(HAVE_INET_NTOA)
  info->server_addr.s_addr = inet_addr(info->server_name);
  if (info->server_addr.s_addr != INADDR_NONE) return 0;
#else
  if (inet_aton(info->server_name, &info->server_addr) != 0) return 0;
#endif
  
  host = gethostbyname(info->server_name);
  if (host == NULL) {
    rtsp_debug(LOG_CRIT, "Can't get server host name %s", info->server_name);
    return (h_errno);
  }
  info->server_addr = *(struct in_addr *)host->h_addr;
#endif
  return 0;
}

int rtsp_create_socket (rtsp_client_t *info)
{
#ifndef HAVE_IPv6
  struct sockaddr_in sockaddr;
#endif
  int result;

  // Do we have a socket already - if so, go ahead

  if (info->server_socket != -1) {
    return (0);
  }
  
  if (info->server_name == NULL) {
    rtsp_debug(LOG_CRIT, "No server name in create socket");
    return (-1);
  }
  result = rtsp_get_server_address(info);
  if (result != 0) return -1;
  
#ifndef _WIN32
#ifdef HAVE_IPv6
  info->server_socket = socket(info->addr_info->ai_family,
			       info->addr_info->ai_socktype,
			       info->addr_info->ai_protocol);
#else
  info->server_socket = socket(AF_INET, SOCK_STREAM, 0);
#endif
#else
  info->server_socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
#endif

  if (info->server_socket == -1) {
    rtsp_debug(LOG_CRIT, "Couldn't create socket");
    return (-1);
  }

  
#ifndef HAVE_IPv6  
  sockaddr.sin_family = AF_INET;
  sockaddr.sin_port = htons(info->port);
  sockaddr.sin_addr = info->server_addr;
#endif

#ifndef _WIN32
  result = connect(info->server_socket,
#ifndef HAVE_IPv6
		   (struct sockaddr *)&sockaddr,
		   sizeof(sockaddr)
#else
		   info->addr_info->ai_addr,
		   info->addr_info->ai_addrlen
#endif
		   );
  if (result < 0)
#else
  result = WSAConnect(info->server_socket, 
	                  (struct sockaddr *)&sockaddr,
					  sizeof(sockaddr), 
					  NULL, 
					  NULL, 
					  NULL, 
					  NULL);
  if (result != 0)
#endif

  {
    rtsp_debug(LOG_CRIT, "Couldn't connect socket - error %s",
	       strerror(errno)
	       );
    return (-1);
  }

  if (info->thread != NULL) {
#ifndef _WIN32
    result = fcntl(info->server_socket, F_GETFL);
    result = fcntl(info->server_socket, F_SETFL, result | O_NONBLOCK);
    if (result < 0) {
      rtsp_debug(LOG_ERR, "Couldn't create nonblocking %s", 
		 strerror(errno)
		 );
    }
#else
	rtsp_thread_set_nonblocking(info);
#endif

  }

  return (0);
}

/*
 * rtsp_send()
 * Sends a buffer over connected socket.  If socket isn't connected,
 * tries that first.
 * Buffer must be formatted to RTSP spec.
 * Inputs:
 *   info - pointer to rtsp_client_t for client session
 *   buff - pointer to buffer
 *   len  - length of buffer
 * Outputs:
 *   0 - success, -1 failure
 */
int rtsp_send (rtsp_client_t *info, const char *buff, uint32_t len)
{
  int ret;

  if (info->server_socket == -1) {
    if (rtsp_create_socket(info) != 0)
      return (-1);
  }
  ret = send(info->server_socket, buff, len, 0);
  return (ret);
}

/*
 * rtsp_receive()
 * Receives a response from server with a timeout.  If recv returns a
 * full buffer, and the last character is not \r or \n, will make a
 * bigger buffer and try to receive.
 *
 * Will set fields in rtsp_client_t.  Relevent fields are:
 *   recv_buff - pointer to receive buffer (malloc'ed so we can always add
 *           \0 at end).
 *   recv_buff_len - max size of receive buffer.
 *   recv_buff_used - number of bytes received.
 *   recv_buff_parsed - used by above routine in case we got more than
 *      1 response at a time.
 */
int rtsp_receive_socket (rtsp_client_t *info, char *buffer, uint32_t len,
			 uint32_t msec_timeout, int wait)
{

  int ret;
#ifdef HAVE_POLL
  struct pollfd pollit;
#else
  fd_set read_set;
  struct timeval timeout;
#endif

  if (msec_timeout != 0 && wait != 0) {
#ifdef HAVE_POLL
    pollit.fd = info->server_socket;
    pollit.events = POLLIN | POLLPRI;
    pollit.revents = 0;

    ret = poll(&pollit, 1, msec_timeout);
#else
    FD_ZERO(&read_set);
    FD_SET(info->server_socket, &read_set);
    timeout.tv_sec = msec_timeout / 1000;
    timeout.tv_usec = (msec_timeout % 1000) * 1000;
    ret = select(info->server_socket + 1, &read_set, NULL, NULL, &timeout);
#endif

    if (ret <= 0) {
      rtsp_debug(LOG_ERR, "Response timed out %d %d", msec_timeout, ret);
      if (ret == -1) {
	rtsp_debug(LOG_ERR, "Error is %s", 
		   strerror(errno));
      }
      return (-1);
    }
  }
  //rtsp_debug(LOG_DEBUG, "Calling recv");
#ifndef _WIN32
  ret = recv(info->server_socket, buffer, len, 0);
#else 
  {
  WSABUF foo;
  int val;
  DWORD flag = 0;
  DWORD bytes;
  foo.buf = buffer;
  foo.len = len;
  val = WSARecv(info->server_socket, &foo, 1, &bytes, &flag, NULL, NULL);
  if (val != 0) {
	  //rtsp_debug(LOG_DEBUG, "error is %d", WSAGetLastError());
	  return -1;
  }
  ret = bytes;
  //rtsp_debug(LOG_DEBUG, "recvd %d bytes", ret);
  }
#endif
  return (ret);
}

/*
 * rtsp_close_socket
 * closes the socket.  Duh.
 */
void rtsp_close_socket (rtsp_client_t *info)
{
  if (info->server_socket != -1)
    closesocket(info->server_socket);
  info->server_socket = -1;
#ifdef HAVE_ST_ADDRINFO
  CHECK_AND_FREE(info,addr_info);
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -