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

📄 dsocket.cpp

📁 一个简单的视频会议VC++MFC工程文件
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////
//    File description : 
//    Name    : DSocket.cpp
//    Details : Datagram Socket for communication
//		 ***  Control Packet Format ***
//		 Type				: 1 byte
//		 Length of hostname : 1 byte
//		 Hostname			: <var>
//
//		 ***  Text packet format ***
//       Type               : 1 byte
//		 Length of hostname	: 1 byte
//		 Hostname           : < var>
//       Length of message  : 2 byte
//		 Message            : <var>
//
//		 ***  Audio packet format ***
//       Type				  : 1 byte
//		 Length of hostname	  : 1 byte
//		 Hostname             : < var>
//       size of audio data   : 2 byte
//		 Audio data           : <var>
//	
//		 ***  Video packet format ***
//       Type                 : 1 byte
//		 Length of hostname	  : 1 byte
//		 Hostname             : < var>
//       size of video data   : 2 byte
//		 Video data           : <var>
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GraghDialog.h"
#include "DSocket.h"
#include "GraghDialogDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

char DSocket::remoteaddress[512]="";
char DSocket::remotename[512]="";

DSocket::DSocket()
{
	m_dlen=0;
	m_data = new char[IMAGE_WIDTH * IMAGE_HEIGHT];
	if(!m_data) AfxMessageBox("DSocket::DSocket 分配缓冲失败");
	else m_dlen=IMAGE_WIDTH * IMAGE_HEIGHT;
}

DSocket::~DSocket()
{
	if(m_data)	delete []m_data;
	m_dlen=0;
}

BOOL DSocket::CreateSocket(int port,int dtype)
{
	type=dtype;
	gethostname(localname,512);	
	switch(type)
	{
	case TYPE_CONTROL:
		rmtport=PORT_CONTROL;
		break;
	case TYPE_AUDIO:
		rmtport=PORT_AUDIO;
		break;
	case TYPE_VIDEO:
		rmtport=PORT_VIDEO;
		break;
	case TYPE_TEXT:
		rmtport=PORT_TEXT;
		break;
	default:
		rmtport=0;
	}

	return Create(port,SOCK_DGRAM);
}

void DSocket::SetParent(CDialog *dlg)
{
	pDlg=dlg;
}

void DSocket::OnReceive(int errcode)
{
	CString address,tmp;
	BOOL	ret=TRUE;
	char hname[512],str[1024],mesg[512];
	unsigned int port=0,retvalue=SOCKET_ERROR;
	int n=0,len=0;
	int ulen=0;

	if(type==TYPE_CONTROL)
	{
		TRACE("DSocket::OnReceive,TYPE_CONTROL,");
		retvalue= ReceiveFrom(m_data,m_dlen,address,port);

		if(retvalue==SOCKET_ERROR && ((CGraghDialogDlg*)pDlg)->m_State==STATE_CALLOUT)
		{
			((CGraghDialogDlg*)pDlg)->m_State = STATE_IDLE;
			((CGraghDialogDlg*)pDlg)->DestroyConference();
			((CGraghDialogDlg*)pDlg)->DisplayMesg("无法连接该联系人");
			return;
		}else if(retvalue==SOCKET_ERROR)	return;
		
		// Get host name from the data.	
		for(int i=0;i<m_data[1];i++)
			hname[i]=m_data[i+2];
		hname[i]=0;
		TRACE("hname=%s,",hname);

		switch(m_data[0])
		{
			// action   : Remote user has sent the invitation for conference
			// reaction : accept(/reject) the invitation
			case MESG_CONNECT:
				TRACE(" from [%s] MESG_CONNECT\n",address);
				((CGraghDialogDlg*)pDlg)->m_State=STATE_CALLIN;
				if(!((CGraghDialogDlg*)pDlg)->m_AutoAccept )
				{
					tmp.Format ("用户 %s 请求连接.\n是否接受该连接?",hname);
					ret=AfxMessageBox(tmp,MB_OKCANCEL);
					if(ret!=IDOK)
					{
						tmp=address;
						strcpy(remoteaddress,(LPCTSTR)address);
						((CGraghDialogDlg*)pDlg)->dcontrol.SendControlMessage(MESG_REJECT,remoteaddress);
						strcpy(remoteaddress,(LPCTSTR)tmp);
						return;
					}
				}
				// maybe wait timeout here,should check it
				if(((CGraghDialogDlg*)pDlg)->m_State==STATE_IDLE) return;
				strcpy(remotename,hname);
				strcpy(remoteaddress,(LPCTSTR)address);
				rmtport = port;
				((CGraghDialogDlg*)pDlg)->StartConference();
				((CGraghDialogDlg*)pDlg)->dcontrol.SendControlMessage(MESG_ACCEPT,remoteaddress);
				sprintf(str,"用户 %s 已连接",hname);
				((CGraghDialogDlg*)pDlg)->DisplayMesg (str);
				return;
			// action   : Remote user has disconnected
			// reaction : destroy the conference
			case MESG_DISCONNECT:
				TRACE("MESG_DISCONNECT\n");
				if(	((CGraghDialogDlg*)pDlg)->m_bStart)
				{
					((CGraghDialogDlg*)pDlg)->DestroyConference();
					sprintf(str,"用户 %s 已离开",hname);
					((CGraghDialogDlg*)pDlg)->DisplayMesg (str);
				}
			return;
			// action   : Remote user has accepted the invitation
			// reaction : start the conference
			case MESG_ACCEPT:
				TRACE("MESG_ACCEPT\n");
				if(	((CGraghDialogDlg*)pDlg)->m_State==STATE_CALLOUT || //FALSE)
					((CGraghDialogDlg*)pDlg)->m_State==STATE_CALLIN )//for local test,commect this while build release version
				{
					strcpy(remotename,hname);
					strcpy(remoteaddress,(LPCTSTR)address);
					((CGraghDialogDlg*)pDlg)->StartConference();
					sprintf(str,"用户 %s 接受您的邀请",hname);
					((CGraghDialogDlg*)pDlg)->DisplayMesg (str);
				}
				return;
			// action   : Remote user has rejected the invitation
			// reaction : what to do...?
			case MESG_REJECT:
				TRACE("MESG_REJECT\n");
				if(	((CGraghDialogDlg*)pDlg)->m_State!=STATE_CONNECTED)
				{
					((CGraghDialogDlg*)pDlg)->DestroyConference();
					sprintf(str,"用户 %s 拒绝了您的邀请",hname);
					((CGraghDialogDlg*)pDlg)->DisplayMesg (str);
				}
				return;
			default:
				TRACE("MESG_%d\n",m_data[0]);
				return;
		}
		return;
	}

	if(type==TYPE_AUDIO)
	{
//		TRACE("DSocket::OnReceive,TYPE_AUDIO\n");
		retvalue=this->ReceiveFrom(m_data,m_dlen,address,port);
		if(retvalue==SOCKET_ERROR)	return;
		rmtport = port;
		((CGraghDialogDlg*)pDlg)->m_G729aCompress .UnCompress (
				(char *)m_data,retvalue,
				((CGraghDialogDlg*)pDlg)->m_AUnComped,
				&ulen );
		if(ulen>0)
			((CGraghDialogDlg *)pDlg)->m_AudioPlay->PostThreadMessage(WM_PLAYSOUND_PLAYBLOCK,ulen,(LPARAM)((CGraghDialogDlg*)pDlg)->m_AUnComped);
		return;
	}

	if(type==TYPE_VIDEO)
	{
		retvalue=ReceiveFrom(m_data,m_dlen,address,port);
		if(retvalue==SOCKET_ERROR)			return;
//		TRACE("DSocket::OnReceive,TYPE_VIDEO, %d Bytes\n",retvalue);
		rmtport = port;
		((CGraghDialogDlg *)pDlg)->m_VideoCodec.DecodeVideoData(
			m_data,
			retvalue,
			((CGraghDialogDlg *)pDlg)->m_VUnComped,
			&ulen,
			0);
//		TRACE("DSocket::OnReceive,TYPE_VIDEO, %d Bytes,Decoded = %d Bytes\n",retvalue,ulen);
		if(ulen>0)
			((CGraghDialogDlg *)pDlg)->DisplayRemoteFrame((unsigned char*)(((CGraghDialogDlg *)pDlg)->m_VUnComped),ulen);
		return;
	}

	if(type==TYPE_TEXT)
	{
//		TRACE("DSocket::OnReceive,TYPE_TEXT\n");
		retvalue=ReceiveFrom(m_data,m_dlen,address,port);

		if(retvalue==SOCKET_ERROR)		return;
		rmtport = port;

		n=m_data[1];

		for(int i=0;i<n;i++)
			hname[i]=m_data[i+2];
		hname[i]=0;
		
		len=m_data[n+2] | ( m_data[n+3]<<8 );

		memcpy(mesg,&m_data[n+4],len);
		mesg[len]=0;

		sprintf(str,"[%s] >> %s ",hname,mesg);

		// Display message
		((CGraghDialogDlg *)pDlg)->m_TextChatDlg .DisplayRemoteMessage (hname,mesg,-1);
		return;
	}
}

BOOL DSocket::SendControlMessage(int type,char *address)
{
	int n;
	BOOL	ret;
	m_data[0]=type;				

	// Length of hostname
	n=strlen(localname);	
	m_data[1]=n;					
	
	// Name of the sender host

	memcpy(&m_data[2],localname,n);

	TRACE("DSocket::SendControlMessage ");
	switch(type)
	{
	case MESG_CONNECT:
		TRACE("MESG_CONNECT");
		break;
	case MESG_DISCONNECT:
		TRACE("MESG_DISCONNECT");
		break;
	case MESG_ACCEPT:
		TRACE("MESG_ACCEPT");
		break;
	case MESG_REJECT:
		TRACE("MESG_REJECT");
		break;
	default:
		TRACE("MESG_UNKNOWN");
		break;
	}

	if(address==NULL)
	{
		TRACE(" to (%s)\n",remoteaddress);
//		SendTo(data,n+2,PORT_CONTROL,remoteaddress);
		ret=SendTo(m_data,n+2,rmtport,remoteaddress);
	}else
	{
		TRACE(" to (%s)\n",address);
//		SendTo(data,n+2,PORT_CONTROL,address);
		ret=SendTo(m_data,n+2,rmtport,address);
	}
	return (ret!=SOCKET_ERROR);
}

void DSocket::SendAudioData(unsigned char *data,int length)
{
//	TRACE("DSocket::SendAudioData %d Bytes\n",length);
//	SendTo(data,length,PORT_AUDIO,remoteaddress);
	if(strlen(remoteaddress)<=1)
	{
		CopyMemory(remoteaddress,((CGraghDialogDlg *)pDlg)->dcontrol .remoteaddress,sizeof(remoteaddress));
		CopyMemory(remotename,((CGraghDialogDlg *)pDlg)->dcontrol .remotename,sizeof(remotename));
	}
	SendTo(data,length,rmtport,remoteaddress);
}

void DSocket::SendVideoData(unsigned char *data,int length)
{
//	SendTo(data,length,PORT_VIDEO,remoteaddress);
	if(strlen(remoteaddress)<=1)
	{
		CopyMemory(remoteaddress,((CGraghDialogDlg *)pDlg)->dcontrol .remoteaddress,sizeof(remoteaddress));
		CopyMemory(remotename,((CGraghDialogDlg *)pDlg)->dcontrol .remotename,sizeof(remotename));
	}
	SendTo(data,length,rmtport,remoteaddress);
//	TRACE("DSocket::SendVideoData %s %d Bytes\n",remoteaddress,length);
}

void DSocket::SendTextData(unsigned char *data,short length)
{
	int n;	

	// Text message
	m_data[0]=TYPE_TEXT;
	
	// Length of hostname
	n=strlen(localname);
	m_data[1]=n;
	
	// Hostname
	memcpy(&m_data[2],localname,n);

	// Data length
	m_data[n+2]=(unsigned char) length;
	m_data[n+3]=(unsigned char) (length>>8);

	// Data
	memcpy(&m_data[n+4],data,length);
//	TRACE("DSocket::SendTextData %d Bytes\n",length);
//	SendTo(packet,n+4+length,PORT_TEXT,remoteaddress);
	if(strlen(remoteaddress)<=1)
	{
		CopyMemory(remoteaddress,((CGraghDialogDlg *)pDlg)->dcontrol .remoteaddress,sizeof(remoteaddress));
		CopyMemory(remotename,((CGraghDialogDlg *)pDlg)->dcontrol .remotename,sizeof(remotename));
	}
	SendTo(m_data,n+4+length,rmtport,remoteaddress);
}

void DSocket::CloseSocket()
{
	DSocket::Close();
}

⌨️ 快捷键说明

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