程序还没有写完出现一大堆问题,请各位帮帮忙啊。我写的是一个视频流转发程序,如果哪位有成熟的代码,请发一份让我参考参考,谢谢。要分没问题,有10000多分没处花啊。

解决方案 »

  1.   

    // RTSPServedlg->cpp : implementation file
    //#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;
    }
      

  2.   


    /*--------------------------------------------------------------------------------
     函数功能:客户端视频端播放请求侦听线程
    --------------------------------------------------------------------------------*/
    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;
    }
      

  3.   

    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);
    }
      

  4.   

    这么不好看,请将代码发到
    [email protected]
      

  5.   

    我刚做完一个转发视频的服务器,已经交工。
    和我联系。[email protected]
      

  6.   

    是不是Lock/UnLock不配对。
    CCriticalSection/CSingleLock?
    我用.net2003编译你的程序,到目前为止很正常。