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

📄 network_ctrl_send_thread.cpp

📁 视频会议源码
💻 CPP
字号:
///////////////////////////////////////////////////////// FileName:	network_ctrl_send_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 "network_ctrl_send_thread.h"#include "network_audio_send_thread.h"#include "network_video_send_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"using namespace std;///////////////////////////////////////////////////////// Public Functions///////////////////////////////////////////////////////// 构造函数// 传入参数为// nc_in 上层network_ctrl对象指针// stackSize QThread所用的参数network_ctrl_send_thread::network_ctrl_send_thread ( avi * avi_ptr_in, network_ctrl * nc_in, unsigned int stackSize )		:QThread( stackSize ) // {{{{	verbose_output( 2, "create network_ctrl_send_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;	nast = NULL;	nvst = NULL;	avi_ptr = avi_ptr_in;	client_num = 0;} // }}}// 析构函数network_ctrl_send_thread::~network_ctrl_send_thread ( void ) // {{{{	if ( 0 != fd_ctrl )	{		close( fd_ctrl );	}	if ( NULL != nast )	{		if ( nast->running() )		{			nast->terminate();			cerr << "Warning! Terminate network audio send thread." << endl;		}		delete nast;	}	if ( NULL != nvst )	{		if ( nvst->running() )		{			nvst->terminate();			cerr << "Warning! Terminate network video send thread." << endl;		}		delete nvst;	}	delete [] recv_buff;	delete [] send_buff;	delete addr_accept;	delete acclen;} // }}}// 运行部分,线程代码在这里void network_ctrl_send_thread::run ( void ) // {{{{	verbose_output( 1, "network ctrl send thread running..." );	if ( avi_ptr->use_multicast )	{		listen_init_mc();	}	else	{		listen_init();	}	if ( avi_ptr->va_mode != AUDIO_ONLY )	{		// 使用视频		nvst = new network_video_send_thread( avi_ptr, nc );		nvst->start();	}	if ( avi_ptr->va_mode != VIDEO_ONLY )	{		// 使用音频		nast = new network_audio_send_thread( avi_ptr, nc );		nast->start();	}	if ( avi_ptr->use_multicast )	{		listen_handle_mc();	}	else	{		listen_handle();	}	return;} // }}}///////////////////////////////////////////////////////// Private Functions///////////////////////////////////////////////////////// 连接初始化,创建套接字void network_ctrl_send_thread::listen_init ( void ) // {{{{	verbose_output( 3, "net_mode LISTEN" );	/////////////////////////////////////////	// 创建控制端口	sockaddr_in addr_listen;	socklen_t len = sizeof( addr_listen );	int port = DEFAULT_CTRL_PORT;		// 创建一个等待server daemon的监听端口	// 创建控制端监听socket	verbose_output( 3, "creating listen socket..." );	fd_ctrl = socket( AF_INET, SOCK_DGRAM, 0 );			// 绑定指定端口	memset( &addr_listen, 0, sizeof( addr_listen ) );	addr_listen.sin_family = AF_INET;	addr_listen.sin_addr.s_addr = htonl( INADDR_ANY );	addr_listen.sin_port = htons( port );		// 绑定端口	if ( bind( fd_ctrl, (sockaddr*) & addr_listen, len ) == -1 )	{		cerr << "Can't bind to the listen port [" << port << "]" << endl;		::exit( 1 );	}	verbose_output( 3, "waiting for connection...", avi_ptr->ip );	*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );} // }}}// 处理连接后的数据发送工作void network_ctrl_send_thread::listen_handle ( void ) // {{{{	// 接收进来的连接	int recv_num;	BUFF * buff;	bool should_exit = false;	int lost_heartbeat = 0;	packet_head_t * packet_head = NULL;	while ( 1 )	{		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			cout << "before nast" << endl;			nast->wait();			cout << "after nvst" << endl;			cout << "before nvst" << endl;			nvst->wait();			cout << "after nvst" << endl;			QCustomEvent * event = new QCustomEvent( SIG_STOP_OK );			QApplication::postEvent( avi_ptr, event );			return;		}		// 监听端口		pollfd connect_in = { fd_ctrl, POLLIN, 0 };		int result = poll( &connect_in, 1, DEFAULT_TIMEOUT );		if ( result < 0 )		{			perror( "Error in video listening" );		}				if ( result == 0 && client_num > 0 ) // {{{		{			// 超时,无heartbeat			lost_heartbeat++;						if ( lost_heartbeat >= MAX_LOST_HEARTBEAT )			{				// 客户端丢失				QCustomEvent * event = new QCustomEvent( SIG_LOST_CLIENT );				QApplication::postEvent( avi_ptr, event );				client_num--;				nast->wait();				nvst->wait();				return;			}		}		else		{			// 有数据可读?			if ( ( connect_in.revents & POLLIN ) != 0 ) // {{{			{				recv_line( fd_ctrl, addr_accept, recv_buff, buff, packet_head );				if ( TEST_CTRL_SYN_BIT( packet_head->opt_bits ) )				{					packet_num = recv_num;					QCustomEvent * event = new QCustomEvent( SIG_ACCEPT_CONNECT );					QApplication::postEvent( avi_ptr, event );					client_num++;					// 写入参数					option_t opt_buf;					opt_buf.factor = avi_ptr->video_opt.factor;					opt_buf.va_mode = avi_ptr->va_mode;					if ( avi_ptr->use_g723 )					{						opt_buf.use_g723 = 1;					}					else					{						opt_buf.use_g723 = 0;					}					int length = sizeof( opt_buf );					send_data( fd_ctrl, addr_accept, send_buff, (BUFF *) &opt_buf, length, packet_num, SYN );					verbose_output( 4, "transfer 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", avi_ptr->use_g723 );				}				else				{					if ( TEST_CTRL_HEARTBEAT_BIT( packet_head->opt_bits ) )					{						lost_heartbeat = 0;					}					else					{						if ( TEST_CTRL_GOODBYE_BIT( packet_head->opt_bits ) )						{							// 客户端正常退出							QCustomEvent * event = new QCustomEvent( SIG_ACCEPT_DISCONNECT );							QApplication::postEvent( avi_ptr, event );							nast->wait();							nvst->wait();							client_num--;							return;						}					}				}			} // if ( ( connect_in.revents & POLLIN ) != 0 ) }}}		} // if ( result == 0 ) // }}}	} // while ( 1 )	return;} // }}}// 组播初始化,创建套接字void network_ctrl_send_thread::listen_init_mc ( void ) // {{{{	verbose_output( 3, "network ctrl send thread Multicast init." );	/////////////////////////////////////////	// 创建控制端口	/////////////////////////////////////////		*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );		// 网络连接的参数设置	addr_accept->sin_family = AF_INET;	addr_accept->sin_port = htons( DEFAULT_MC_CTRL_PORT );	inet_pton( AF_INET, static_cast< const char* >( avi_ptr->mc_addr ), 			&addr_accept->sin_addr );	// 创建控制端发送socket	fd_ctrl = socket( AF_INET, SOCK_DGRAM, 0 );		// 初始化组播	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 ) );	verbose_output( 3, "ready to send data", avi_ptr->ip );} // }}}// 处理组播连接后的数据接收工作void network_ctrl_send_thread::listen_handle_mc ( void ) // {{{{	verbose_output( 3, "network ctrl send thread Multicast handle." );	nast->wait();	cout << "nast wait" << endl;	nvst->wait();	cout << "nvst wait" << endl;} // }}}

⌨️ 快捷键说明

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