gusucode.com > 基于VC++的局域网视频聊天系统源码程序 > 基于VC++的局域网视频聊天系统源码程序/code/ChatClient/DSocket.cpp
// DSocket.cpp: implementation of the DSocket class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ChatClientDlg.h" #include "DSocket.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// char DSocket::remoteaddress[512]=""; char DSocket::remotename[512]=""; DSocket::DSocket() { m_dlen=0; m_data = new char[IMAGE_WIDTH * IMAGE_HEIGHT*10]; memset(m_data, 0, IMAGE_WIDTH * IMAGE_HEIGHT*10); if(!m_data) AfxMessageBox("DSocket::DSocket 分配缓冲失败"); else m_dlen=IMAGE_WIDTH * IMAGE_HEIGHT*10; } 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; default: rmtport=0; } return Create(port,SOCK_DGRAM); } void DSocket::SetParent(CDialog *dlg) { pDlg=dlg; } 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); switch(type) { case MESG_CONNECT: break; case MESG_DISCONNECT: break; case MESG_ACCEPT: break; case MESG_REJECT: break; default: break; } if(address==NULL) { ret=SendTo(m_data,n+2,rmtport,remoteaddress); }else { ret=SendTo(m_data,n+2,rmtport,address); } return (ret!=SOCKET_ERROR); } void DSocket::SendAudioData(unsigned char *data, int length) { if(strlen(remoteaddress)<=1) { CopyMemory(remoteaddress,((CChatClientDlg *)pDlg)->dcontrol .remoteaddress,sizeof(remoteaddress)); CopyMemory(remotename,((CChatClientDlg *)pDlg)->dcontrol .remotename,sizeof(remotename)); } SendTo(data,length,rmtport,remoteaddress); } void DSocket::SendVideoData(unsigned char *data, int length) { if(strlen(remoteaddress)<=1) { CopyMemory(remoteaddress,((CChatClientDlg *)pDlg)->dcontrol .remoteaddress,sizeof(remoteaddress)); CopyMemory(remotename,((CChatClientDlg *)pDlg)->dcontrol .remotename,sizeof(remotename)); } Sleep(1); int iRet=SendTo(data,length,rmtport,remoteaddress); DWORD dw=GetLastError(); } void DSocket::OnReceive(int errcode) { CString address,tmp; BOOL ret=TRUE; char hname[512],str[1024]; 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 && ((CChatClientDlg*)pDlg)->m_State==STATE_CALLOUT) { ((CChatClientDlg*)pDlg)->m_State = STATE_IDLE; ((CChatClientDlg*)pDlg)->DestroyVideo(); 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; switch(m_data[0]) { // action : Remote user has sent the invitation for conference // reaction : accept(/reject) the invitation case MESG_CONNECT: ((CChatClientDlg*)pDlg)->m_State=STATE_CALLIN; tmp.Format ("用户 %s 请求连接.\n是否接受该连接?",hname); ret=AfxMessageBox(tmp,MB_OKCANCEL); if(ret!=IDOK) { tmp=address; strcpy(remoteaddress,(LPCTSTR)address); ((CChatClientDlg*)pDlg)->dcontrol.SendControlMessage(MESG_REJECT,remoteaddress); strcpy(remoteaddress,(LPCTSTR)tmp); return; } // maybe wait timeout here,should check it if(((CChatClientDlg*)pDlg)->m_State==STATE_IDLE) return; strcpy(remotename,hname); strcpy(remoteaddress,(LPCTSTR)address); rmtport = port; ((CChatClientDlg*)pDlg)->StartVideo(); ((CChatClientDlg*)pDlg)->dcontrol.SendControlMessage(MESG_ACCEPT,remoteaddress); sprintf(str,"用户 %s 已连接",hname); return; // action : Remote user has disconnected // reaction : destroy the conference case MESG_DISCONNECT: if( ((CChatClientDlg*)pDlg)->m_bStart) { ((CChatClientDlg*)pDlg)->DestroyVideo(); } return; // action : Remote user has accepted the invitation // reaction : start the conference case MESG_ACCEPT: if( ((CChatClientDlg*)pDlg)->m_State==STATE_CALLOUT || //FALSE) ((CChatClientDlg*)pDlg)->m_State==STATE_CALLIN )//for local test,commect this while build release version { strcpy(remotename,hname); strcpy(remoteaddress,(LPCTSTR)address); ((CChatClientDlg*)pDlg)->StartVideo(); } return; // action : Remote user has rejected the invitation // reaction : what to do...? case MESG_REJECT: if( ((CChatClientDlg*)pDlg)->m_State!=STATE_CONNECTED) { ((CChatClientDlg*)pDlg)->DestroyVideo(); } return; default: return; } return; } if(type==TYPE_AUDIO) { retvalue=this->ReceiveFrom(m_data,m_dlen,address,port); if(retvalue==SOCKET_ERROR) return; rmtport = port; ((CChatClientDlg*)pDlg)->m_G729aCompress .UnCompress ( (char *)m_data,retvalue, ((CChatClientDlg*)pDlg)->m_AUnComped, &ulen ); if(ulen>0) ((CChatClientDlg *)pDlg)->m_AudioPlay->PostThreadMessage(WM_PLAYSOUND_PLAYBLOCK,ulen,(LPARAM)((CChatClientDlg*)pDlg)->m_AUnComped); return; } if(type==TYPE_VIDEO) { retvalue=ReceiveFrom(m_data,m_dlen,address,port); if(retvalue==SOCKET_ERROR) return; rmtport = port; ((CChatClientDlg *)pDlg)->m_VideoCodec.DecodeVideoData( m_data, retvalue, ((CChatClientDlg *)pDlg)->m_VUnComped, &ulen, 0); if(ulen>0) ((CChatClientDlg *)pDlg)->m_LocalDlg.DisplayRemoteFrame((unsigned char*)(((CChatClientDlg *)pDlg)->m_VUnComped),ulen); return; } } void DSocket::CloseSocket() { DSocket::Close(); }