BOOL CRTSPServeDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control }void CRTSPServeDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } }// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void CRTSPServeDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } }// The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CRTSPServeDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }void CRTSPServeDlg::OnButton1() { // TODO: Add your control notification handler code here m_OptHikSKDEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);//TRUE 表示人工重置信号,FALSE表示初始为无信号 ::SetEvent(m_OptHikSKDEvent); //设置为有信号 m_hMutexPlay=NULL; m_hMutexPlay = CreateMutex(NULL, FALSE, NULL); m_hMutexTransmit=NULL; m_hMutexTransmit = CreateMutex(NULL, FALSE, NULL); DWORD dwThreadID=0; HANDLE h =::CreateThread(NULL,0,ControlThread, (LPVOID)NULL,0,&dwThreadID);//初始化服务器监听线程 CloseHandle(h); }
//#include "stdafx.h"
#include "RTSPServe.h"
#include "RTSPServedlg.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CRTSPServeDlg * dlg;
CString m_ErrorMsg;//错误信息
char m_playcode[6]={0x2d,0x00,0x00,0x00,0x3c,0x03}; //播放指令码
char m_autherror[6]={0x4d,0x40,0x40,0x00,0x3c,0x3d}; //认证错误或网络不通
char m_codeerror[6]={0x3d,0x30,0x30,0x00,0x3c,0x3d}; //指令码错误int iPort=2998;
int ARRAYNUM=100;
/////////////////////////////////////////////////////////////////////////////
// CRTSPServeDlg dialogCRTSPServeDlg::CRTSPServeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRTSPServeDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CRTSPServeDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CRTSPServeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRTSPServeDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CRTSPServeDlg, CDialog)
//{{AFX_MSG_MAP(CRTSPServeDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_WM_CREATE()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CRTSPServeDlg message handlers
/*--------------------------------------------------------------------------------
函数功能:发送视频流到当前客户机中
--------------------------------------------------------------------------------*/
DWORD WINAPI SendStreamToClient(LPVOID n)
{
return 0;
}
/*--------------------------------------------------------------------------------
函数功能:客户端视频播放通信线程
--------------------------------------------------------------------------------*/DWORD WINAPI CommunicationThread(LPVOID n)
{
SOCKET m_client=(SOCKET)n;
bool bFirstRecv=true; int iRet=0;
int ret=0;//select 返回值
char szRecvFromClientBuff[clientBuffSize]={0};
fd_set fdread,fdwrite; char m_server_ip[20];//视频服务器 地址
char m_channel=0;//通道号
WORD m_port=0; while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(m_client,&fdwrite);
FD_SET(m_client,&fdread);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
break;
if(ret>0)
{
if(FD_ISSET(m_client,&fdread))
{
//接收m_client发送来的数据//
memset(szRecvFromClientBuff,0,clientBuffSize);
iRet=recv(m_client,szRecvFromClientBuff,clientBuffSize,0);
if(iRet==SOCKET_ERROR)
break;
else if(iRet==0)
break; if(iRet==75)
{
//进行操作指令分析
} else if(bFirstRecv)
{
bFirstRecv=false;
//校验指令
int b=sizeof(RequestPlayRealStream);
if(iRet!=b)
{
break;
}
else //取指令内容
{
ret=dlg->CheckCommand(&m_client,szRecvFromClientBuff,iRet);
if(ret==0)
{
//指令码错误,断开连接
send(m_client,m_codeerror,sizeof(m_codeerror),0);
break;
}
else if (ret==1)
{
//指令及认证通过,添加新的转播对象
// pRequestPlayRealStream pRequest=new RequestPlayRealStream;
memcpy(pRequest,szRecvFromClientBuff,iRet); //转成标准IP
sprintf(m_server_ip,"%u.%u.%u.%u",
(UINT)(pRequest->m_server_ip[0]), (UINT)(pRequest->m_server_ip[1]),
(UINT)(pRequest->m_server_ip[2]), (UINT)(pRequest->m_server_ip[3])); m_channel=pRequest->m_channel;
m_port=pRequest->m_port;
delete pRequest;
pRequest=NULL;
//theApp.WriteLog("新客户机连接成功:"+CString(m_server_ip));
}
else if (ret==2)
{
//用户认证错误,或网络不通cd
send(m_client,m_autherror,sizeof(m_autherror),0);
break;
}
} }//if(bFirstRecv) }
else
{
Sleep(10);
}
}
} closesocket(m_client); //将当前client对象从转播列表中删除
pTransmitRealStreamClientInfo TransmitInfos=new TransmitRealStreamClientInfo();
TransmitInfos->m_channel=m_channel;
strcpy(TransmitInfos->m_server_ip,m_server_ip);
TransmitInfos->m_s=m_client; dlg->DeleteTransmitObject(TransmitInfos);
delete TransmitInfos;
TransmitInfos=NULL; if(dlg->GetTransmitObject(m_server_ip,m_channel)==0)
{
//删除当前主播对象并停止播放
pPlayRealStreamInfo PlayObjectInfo=new PlayRealStreamInfo;
PlayObjectInfo->m_channel=m_channel;
PlayObjectInfo->m_port=m_port;
strcpy(PlayObjectInfo->m_server_ip,m_server_ip);
dlg->DelePlayObject(PlayObjectInfo);
delete PlayObjectInfo;
PlayObjectInfo=NULL;
} return 0;
}
/*--------------------------------------------------------------------------------
函数功能:客户端视频端播放请求侦听线程
--------------------------------------------------------------------------------*/
DWORD WINAPI ControlThread(LPVOID hWnd)
{
/*
控制Bind Socket线程使用TCP通信服务端口为7998
*/
struct sockaddr_in Sockaddr,ClieAddr;
SOCKET m_socket=INVALID_SOCKET; m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//TCP
if(m_socket==INVALID_SOCKET)
return -1;
Sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
Sockaddr.sin_family=AF_INET;
Sockaddr.sin_port=htons(iPort); //7998是控制服务端口
if(bind(m_socket,(struct sockaddr *)&Sockaddr,sizeof(Sockaddr))==SOCKET_ERROR)
{
m_ErrorMsg="绑定端口出错,端口已被占用。";
//theApp.WriteLog(m_ErrorMsg);
return -1;
}
if (listen(m_socket, SOMAXCONN) == SOCKET_ERROR)
{
//Error("Listen");
m_ErrorMsg="启动侦听出错。";
//theApp.WriteLog(m_ErrorMsg);
return -1;
}
int addrlen=0;
addrlen = sizeof(ClieAddr); while (1)
{
SOCKET m_client = accept(m_socket, (sockaddr*)&ClieAddr, &addrlen); if (m_client == INVALID_SOCKET)
{
;//继续
}
else
{
if(dlg->pTransmitInfos.size()<ARRAYNUM)
{
//创建一个指令交互线程
DWORD dwThreadID=0;
HANDLE h =::CreateThread(NULL,0,CommunicationThread, (LPVOID)m_client,0,&dwThreadID);
CloseHandle(h);
}
else
{
//超出最大连接数,断开当前连接
closesocket(m_client);
//theApp.WriteLog("错误:("+I2S(ARRAYNUM)+") 客户机连接已超出最大连接数!");
} } Sleep(100);
}
return 0;
}
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}void CRTSPServeDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.void CRTSPServeDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CRTSPServeDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}void CRTSPServeDlg::OnButton1()
{
// TODO: Add your control notification handler code here
m_OptHikSKDEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);//TRUE 表示人工重置信号,FALSE表示初始为无信号
::SetEvent(m_OptHikSKDEvent); //设置为有信号 m_hMutexPlay=NULL;
m_hMutexPlay = CreateMutex(NULL, FALSE, NULL); m_hMutexTransmit=NULL;
m_hMutexTransmit = CreateMutex(NULL, FALSE, NULL); DWORD dwThreadID=0;
HANDLE h =::CreateThread(NULL,0,ControlThread, (LPVOID)NULL,0,&dwThreadID);//初始化服务器监听线程
CloseHandle(h);
}
[email protected]
和我联系。[email protected]
CCriticalSection/CSingleLock?
我用.net2003编译你的程序,到目前为止很正常。