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

📄 network_ctrl_recv_thread.cpp

📁 视频会议源码
💻 CPP
字号:
///////////////////////////////////////////////////////// FileName:	network_ctrl_recv_thread.cpp// Author:		b1gm0use// Project:		myvideo#include <iostream>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <qapplication.h>#include <qthread.h>#include <poll.h>#include <qevent.h>#include <linux/if.h>#include "network_ctrl_recv_thread.h"#include "network_audio_recv_thread.h"#include "network_video_recv_thread.h"#include "video_cap.h"#include "capture_event.h"#include "video_send.h"#include "network_audio_send.h"#include "network_video_send.h"#include "network_ctrl.h"#include "video.h"#include "network.h"#include "common.h"#include "audio.h"#include "avi.h"#include "signal_def.h"#include "capture_event.h"using namespace std;///////////////////////////////////////////////////////// Public Functions///////////////////////////////////////////////////////// 构造函数// 传入参数为// nc_in 上层network_ctrl对象指针// stackSize QThread所用的参数network_ctrl_recv_thread::network_ctrl_recv_thread ( avi * avi_ptr_in, 		network_ctrl * nc_in, unsigned int stackSize )		:QThread( stackSize ) // {{{{	verbose_output( 2, "create network_ctrl_recv_thread." );	nc = nc_in;	fd_ctrl = 0;	recv_buff = new BUFF [ PACKET_LENGTH ];	send_buff = new BUFF [ PACKET_LENGTH ];	addr_accept = new sockaddr_in;	acclen = new socklen_t;	packet_num = 0;	expect_num = 0;	nart = NULL;	nvrt = NULL;	avi_ptr = avi_ptr_in;} // }}}// 析构函数network_ctrl_recv_thread::~network_ctrl_recv_thread ( void ) // {{{{	if ( 0 != fd_ctrl )	{		close( fd_ctrl );	}	if ( NULL != nart )	{		if ( nart->running() )		{			nart->terminate();			cerr << "Warning! Terminate network audio recv thread." << endl;		}		delete nart;	}	if ( NULL != nvrt )	{		if ( nvrt->running() )		{			nvrt->terminate();			cerr << "Warning! Terminate network video recv thread." << endl;		}		delete nvrt;	}	delete [] recv_buff;	delete [] send_buff;	delete addr_accept;	delete acclen;} // }}}// 运行部分,线程代码在这里void network_ctrl_recv_thread::run ( void ) // {{{{	verbose_output( 1, "network ctrl recv thread running..." );	int init_ok;	if ( avi_ptr->use_multicast )	{		init_ok = connect_init_mc();	}	else	{		init_ok = connect_init();	}	if ( init_ok == SUCCEED )	{		if ( avi_ptr->va_mode != AUDIO_ONLY )		{			verbose_output( 1, "create new network_video_recv_thread." );			nvrt = new network_video_recv_thread( avi_ptr, nc );			nvrt->start();		}		if ( avi_ptr->va_mode != VIDEO_ONLY )		{			verbose_output( 1, "create new network_audio_recv_thread." );			nart = new network_audio_recv_thread( avi_ptr, nc );			nart->start();		}		if ( avi_ptr->use_multicast )		{			connect_handle_mc();		}		else		{			connect_handle();		}	}	verbose_output( 1, "end of network_audio_recv_thread" );	return;} // }}}///////////////////////////////////////////////////////// Private Functions///////////////////////////////////////////////////////// 连接初始化,创建套接字int network_ctrl_recv_thread::connect_init ( void ) // {{{{	verbose_output( 3, "network_ctrl_recv_thread init." );	//expect_num = WELCOME_NUM;	*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );	// 网络连接的参数设置	addr_accept->sin_family = AF_INET;	addr_accept->sin_port = htons( DEFAULT_CTRL_PORT );	inet_pton( AF_INET, static_cast< const char* > ( avi_ptr->ip ), &addr_accept->sin_addr );	verbose_output( 3, "creating ctrl connect socket..." );	fd_ctrl = socket( AF_INET, SOCK_DGRAM, 0 );		pollfd connect_to = { fd_ctrl, POLLIN, 0, };	bool read_ok = false;	option_t * opt_buf = NULL;	BUFF * temp;	int connect_times = 0;	bool should_exit = false;	packet_head_t * packet_head = NULL;	do	{		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			QCustomEvent * event = new QCustomEvent( SIG_DISCONNECT_OK );			QApplication::postEvent( avi_ptr, event );			return FAILED;		}		verbose_output( 3, "send ctrl Hello message ..." );		send_data( fd_ctrl, addr_accept, send_buff, NULL, 0, expect_num, SYN );		int result = poll( &connect_to, 1, DEFAULT_TIMEOUT );		if ( result == 0 )		{			// 超时返回			connect_times++;			if ( connect_times >= DEFAULT_CONNECT_TIMES )			{				cerr << "Warning! Can't connect to peer host." << endl;				QCustomEvent * event = new QCustomEvent( SIG_CONNECT_TIMEOUT );				QApplication::postEvent( avi_ptr, event );				return FAILED;			}			continue;		}		else		{			if ( result > 0 )			{				// 网络可读				recv_line( fd_ctrl, addr_accept, recv_buff, temp, packet_head );				opt_buf = (option_t *) temp;				if ( !TEST_CTRL_SYN_BIT( packet_head->opt_bits ) )				{					cerr << "Warning! not the Welcome reply." << endl;				}				else				{					read_ok = true;				}			}			else			{				// 套接口错误				perror( "Error in connecting" );				::exit( 1 );			}		}	}	while ( !read_ok );	expect_num++;	QCustomEvent * event = new QCustomEvent( SIG_CONNECT_OK );	QApplication::postEvent( avi_ptr, (QEvent*) event );	// 获得参数设置	avi_ptr->va_mode = opt_buf->va_mode;	avi_ptr->video_opt.factor = opt_buf->factor;		if ( opt_buf->use_g723 == 0 )	{		avi_ptr->use_g723 = false;	}	else	{		if ( opt_buf->use_g723 == 1 )		{			avi_ptr->use_g723 = true;		}	}	verbose_output( 4, "get peer configuration" );	verbose_output( 4, "va_mode\t", avi_ptr->va_mode );	verbose_output( 4, "factor\t", avi_ptr->video_opt.factor );	verbose_output( 4, "use_g723\t", opt_buf->use_g723 );	return SUCCEED;} // }}}// 处理连接后的数据发送工作void network_ctrl_recv_thread::connect_handle ( void ) // {{{{	bool should_exit = false;	int count = 0;		while( 1 )	{		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			send_data( fd_ctrl, addr_accept, send_buff, NULL, 0, packet_num, GOODBYE );			QCustomEvent * event = new QCustomEvent( SIG_DISCONNECT_OK );			QApplication::postEvent( avi_ptr, event );			nart->wait();			cout << " wait nart ok " << endl;			nvrt->wait();			cout << " wait nvrt ok " << endl;			return;		}		msleep( HEARTBEAT_INTERVAL / 4 );		count = ( count + 1 ) % 4;		if ( count == 3 )		{			cout << "send heartbeat" << endl;			send_data( fd_ctrl, addr_accept, send_buff, NULL, 0, packet_num, HEARTBEAT );		}	}	return;} // }}}// 组播初始化,创建套接字int network_ctrl_recv_thread::connect_init_mc ( void ) // {{{{	verbose_output( 3, "network ctrl recv thread Multicast init." );	/////////////////////////////////////////	// 创建控制端口	/////////////////////////////////////////		*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );	// 创建控制端监听socket	verbose_output( 3, "creating multicast listen socket..." );	fd_ctrl = socket( AF_INET, SOCK_DGRAM, 0 );			// 绑定指定端口	addr_accept->sin_family = AF_INET;	inet_pton( AF_INET, static_cast< const char* >( avi_ptr->mc_addr ), 			&addr_accept->sin_addr );	addr_accept->sin_port = htons( DEFAULT_MC_CTRL_PORT );		// 绑定端口	if ( bind( fd_ctrl, (sockaddr*) addr_accept, *acclen ) == -1 )	{		cerr << "Can't bind to the listen port [" << DEFAULT_MC_CTRL_PORT << "]" << endl;		::exit( 1 );	}	// 初始化组播	ip_mreq mreq;	memcpy( &mreq.imr_multiaddr, &(((sockaddr_in*) addr_accept)->sin_addr),			sizeof( in_addr ) );	mreq.imr_interface.s_addr = htonl( INADDR_ANY );	// 加入组播组	setsockopt( fd_ctrl, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof( mreq ) );	return SUCCEED;} // }}}// 处理组播连接后的数据接收工作void network_ctrl_recv_thread::connect_handle_mc ( void ) // {{{{	nart->wait();	cout << " wait nart ok " << endl;	nvrt->wait();	cout << " wait nvrt ok " << endl;	QCustomEvent * event = new QCustomEvent( SIG_DISCONNECT_OK );	QApplication::postEvent( avi_ptr, event );	return;} // }}}

⌨️ 快捷键说明

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