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

📄 net_udp.c

📁 完整的RTP RTSP代码库
💻 C
📖 第 1 页 / 共 3 页
字号:
static char *udp_host_addr6(socket_udp *s){#ifdef HAVE_IPv6	char		 hname[MAXHOSTNAMELEN];	int 			 gai_err, newsock;	struct addrinfo 	 hints, *ai;	struct sockaddr_in6 	 local, addr6;	socklen_t len = sizeof(local);	int result = 0;	newsock=socket(AF_INET6, SOCK_DGRAM,0);    memset ((char *)&addr6, 0, len);    addr6.sin6_family = AF_INET6;#ifdef HAVE_SIN6_LEN    addr6.sin6_len    = len;#endif    bind (newsock, (struct sockaddr *) &addr6, len);    addr6.sin6_addr = s->addr6;    addr6.sin6_port = htons (s->rx_port);    connect (newsock, (struct sockaddr *) &addr6, len);    memset ((char *)&local, 0, len);	if ((result = getsockname(newsock,(struct sockaddr *)&local, &len)) < 0){		local.sin6_addr = in6addr_any;		local.sin6_port = 0;		debug_msg("getsockname failed\n");	}	closesocket (newsock);	if (IN6_IS_ADDR_UNSPECIFIED(&local.sin6_addr) || IN6_IS_ADDR_MULTICAST(&local.sin6_addr)) {		if (gethostname(hname, MAXHOSTNAMELEN) != 0) {			debug_msg("gethostname failed\n");			abort();		}				hints.ai_protocol  = 0;		hints.ai_flags     = 0;		hints.ai_family    = AF_INET6;		hints.ai_socktype  = SOCK_DGRAM;		hints.ai_addrlen   = 0;		hints.ai_canonname = NULL;		hints.ai_addr      = NULL;		hints.ai_next      = NULL;		if ((gai_err = getaddrinfo(hname, NULL, &hints, &ai))) {			debug_msg("getaddrinfo: %s: %s\n", hname, gai_strerror(gai_err));			abort();		}				if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr), hname, MAXHOSTNAMELEN) == NULL) {			debug_msg("inet_ntop: %s: \n", hname);			abort();		}		freeaddrinfo(ai);		return xstrdup(hname);	}	if (inet_ntop(AF_INET6, &local.sin6_addr, hname, MAXHOSTNAMELEN) == NULL) {		debug_msg("inet_ntop: %s: \n", hname);		abort();	}	return xstrdup(hname);#else  /* HAVE_IPv6 */	UNUSED(s);	return xstrdup("::");	/* The unspecified address... */#endif /* HAVE_IPv6 */}	/*****************************************************************************//* Generic functions, which call the appropriate protocol specific routines. *//*****************************************************************************//** * udp_addr_valid: * @addr: string representation of IPv4 or IPv6 network address. * * Returns TRUE if @addr is valid, FALSE otherwise. **/int udp_addr_valid(const char *addr){        return udp_addr_valid4(addr) | udp_addr_valid6(addr);}/** * udp_init: * @addr: character string containing an IPv4 or IPv6 network address. * @rx_port: receive port. * @tx_port: transmit port. * @ttl: time-to-live value for transmitted packets. * * Creates a session for sending and receiving UDP datagrams over IP * networks.  * * Returns: a pointer to a valid socket_udp structure on success, NULL otherwise. **/socket_udp *udp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl){	return udp_init_if(addr, NULL, rx_port, tx_port, ttl);}/** * udp_init_if: * @addr: character string containing an IPv4 or IPv6 network address. * @iface: character string containing an interface name. * @rx_port: receive port. * @tx_port: transmit port. * @ttl: time-to-live value for transmitted packets. * * Creates a session for sending and receiving UDP datagrams over IP * networks.  The session uses @iface as the interface to send and * receive datagrams on. *  * Return value: a pointer to a socket_udp structure on success, NULL otherwise. **/socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl){	socket_udp *res;		if (strchr(addr, ':') == NULL) {		res = udp_init4(addr, iface, rx_port, tx_port, ttl);	} else {		res = udp_init6(addr, iface, rx_port, tx_port, ttl);	}	return res;}socket_udp *udp_init_for_receive (const char *iface, uint16_t rx_port, int is_ipv4){  if (is_ipv4) {    return udp_init4(NULL, iface, rx_port, 0, 0);  }  return udp_init6(NULL, iface, rx_port, 0, 0);}/** * udp_exit: * @s: UDP session to be terminated. * * Closes UDP session. *  **/void udp_exit(socket_udp *s){    switch(s->mode) {    case IPv4 : udp_exit4(s); break;    case IPv6 : udp_exit6(s); break;    default   : abort();    }}/** * udp_send: * @s: UDP session. * @buffer: pointer to buffer to be transmitted. * @buflen: length of @buffer. *  * Transmits a UDP datagram containing data from @buffer. *  * Return value: 0 on success, -1 on failure. **/int udp_send(socket_udp *s, const uint8_t *buffer, uint32_t buflen){	switch (s->mode) {	case IPv4 : return udp_send4(s, buffer, buflen);	case IPv6 : return udp_send6(s, buffer, buflen);	default   : abort(); /* Yuk! */	}	return -1;}int udp_sendto (socket_udp *s, const uint8_t *buffer, uint32_t buflen, 		const struct sockaddr *to, const socklen_t tolen){	ASSERT(s != NULL);	ASSERT(buffer != NULL);	ASSERT(buflen > 0);		return sendto(s->fd, buffer, buflen, 0, to, tolen);}#ifdef HAVE_STRUCT_IOVECint udp_send_iov(socket_udp *s, struct iovec *iov, int count){	switch (s->mode) {	case IPv4 : return udp_send_iov4(s, iov, count);	case IPv6 : return udp_send_iov6(s, iov, count);	default   : abort();	}	return -1;}int udp_sendto_iov(socket_udp *s, struct iovec *iov, int count,		   const struct sockaddr *to, const socklen_t tolen){	struct msghdr 		msg;	int ret;	ASSERT(s != NULL);	ASSERT(iov != NULL);	ASSERT(count > 0);		memset(&msg, 0, sizeof(msg));	msg.msg_name 		 = (void *)to;	msg.msg_namelen 	 = tolen;	msg.msg_iov 		 = iov;	msg.msg_iovlen 		 = count;	ret = sendmsg(s->fd, &msg, 0);	if (ret < 0) {	  rtp_message(LOG_ERR, "sendmsg %d %s", 		      errno, strerror(errno));	}	return ret;}#endif/** * udp_recv: * @s: UDP session. * @buffer: buffer to read data into. * @buflen: length of @buffer. *  * Reads from datagram queue associated with UDP session. * * Return value: number of bytes read, returns 0 if no data is available. **/uint32_t udp_recv_with_source (socket_udp *s, uint8_t *buffer, uint32_t buflen,			       struct sockaddr *sock, socklen_t *socklen){	/* Reads data into the buffer, returning the number of bytes read.   */	/* If no data is available, this returns the value zero immediately. */	/* Note: since we don't care about the source address of the packet  */	/* we receive, this function becomes protocol independent.           */	int		len;	ASSERT(buffer != NULL);	ASSERT(buflen > 0);	len = recvfrom(s->fd, buffer, buflen, 0, sock, socklen);	if (len > 0) {		return len;	}	if (errno != ECONNREFUSED) {		socket_error("recvfrom");	}	return 0;}uint32_t udp_recv(socket_udp *s, uint8_t *buffer, uint32_t buflen){	/* Reads data into the buffer, returning the number of bytes read.   */	/* If no data is available, this returns the value zero immediately. */	/* Note: since we don't care about the source address of the packet  */	/* we receive, this function becomes protocol independent.           */  return udp_recv_with_source(s, buffer, buflen, NULL, 0);}struct udp_set_ {  fd_set	rfd;  fd_t	max_fd;};udp_set *udp_init_for_session (void){  return (udp_set *)malloc(sizeof(udp_set));}void udp_close_session (udp_set *s){  free((void *)s);}/** * udp_fd_zero: *  * Clears file descriptor from set associated with UDP sessions (see select(2)). *  **/void udp_fd_zero(udp_set *session){	FD_ZERO(&session->rfd);	session->max_fd = 0;}/** * udp_fd_set: * @s: UDP session. *  * Adds file descriptor associated of @s to set associated with UDP sessions. **/void udp_fd_set(udp_set *session, socket_udp *s){	FD_SET(s->fd, &session->rfd);	if (s->fd > (fd_t)session->max_fd) {		session->max_fd = s->fd;	}}/** * udp_fd_isset: * @s: UDP session. *  * Checks if file descriptor associated with UDP session is ready for * reading.  This function should be called after udp_select(). * * Returns: non-zero if set, zero otherwise. **/int udp_fd_isset(udp_set *session, socket_udp *s){	return FD_ISSET(s->fd, &session->rfd);}/** * udp_select: * @timeout: maximum period to wait for data to arrive. *  * Waits for data to arrive for UDP sessions. *  * Return value: number of UDP sessions ready for reading. **/int udp_select(udp_set *session, struct timeval *timeout){	return select(session->max_fd + 1, &session->rfd, NULL, NULL, timeout);}/** * udp_host_addr: * @s: UDP session. *  * Return value: character string containing network address * associated with session @s. **/char *udp_host_addr(socket_udp *s){  if (s && s->mode == IPv6) {    return udp_host_addr6(s);  }   return udp_host_addr4();}/** * udp_fd: * @s: UDP session. *  * This function allows applications to apply their own socketopt()'s * and ioctl()'s to the UDP session. *  * Return value: file descriptor of socket used by session @s. **/int udp_fd(socket_udp *s){	if (s && s->fd > 0) {		return s->fd;	} 	return 0;}void rtp_set_receive_buffer_default_size (int bufsize){  have_recv_buf_size = 1;  recv_buf_size_value = bufsize;}void udp_set_multicast_src(const char* src){     //TODO - In future use a list and add more that one src     if(src != 	NULL) {         strncpy(G_Multicast_Src, src, sizeof(G_Multicast_Src));         G_IGMP_V3 = 1;     }}

⌨️ 快捷键说明

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