// MulticastSocketReceiveDlg.cpp : 实现文件 // #include "stdafx.h" #include "CH91PayloadSoftware.h" #include "CH91PayloadSoftwareDlg.h" #include "afxdialogex.h" #include "Global.h" #include "GlobalMessage.h" #include "GlobalMember.h" #include "GetElevation.h" #include "MulticastSocketReceiveDlg.h" #include #include // CMulticastSocketReceiveDlg 对话框 //卫通UDP通信端口接收图像数据回调函数 void CALLBACK OnReadFromUDPSACKU( const void* rxdata, int lLen, LPVOID Param ) { if ( lLen > 0) { // 处理数据 SocketReceiveFH96Data(rxdata, lLen); CTime t = GetCurrentTime(); TRACE(_T("%d,%d,%d\n"), lLen,t.GetMinute(), t.GetSecond()); //SocketReceiveH264VideoData(rxdata, lLen); } } IMPLEMENT_DYNAMIC(CMulticastSocketReceiveDlg, CDialogEx) CMulticastSocketReceiveDlg::CMulticastSocketReceiveDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CMulticastSocketReceiveDlg::IDD, pParent) , m_iVideoSrc(0) { //, mStrCDPayLoadIPAddr(_T("0.0.0.0")) // WinSoc m_hThread_GetFH96DataFromNet = NULL; m_ThreadID_GetFH96DataFromNet = 0; // 组播IP str_LocalIP_ReceiveMUDP = _T(""); str_MulticastSocketIP = "233.0.0.1"; m_MulticastSocketPortFH96Data = 8080; str_MulticastSocketInfoReceive = "等待通信连接……\r\n"; //FJ数据显示初始化 m_bFJDataShow = FALSE; //L测控 m_strLLinkMultiCastIP = ""; m_nLLinkMulticastPort = 8000; //卫通组播 m_strSACMulticastIPAddr = ""; m_nSACMulticastRemotePort = 8001; //卫通UDP单播 m_strSACUDPIPAddr = ""; m_nSACUDPRemotePort = 2203; m_nSACUDPLocalPort = 8002; } CMulticastSocketReceiveDlg::~CMulticastSocketReceiveDlg() { } void CMulticastSocketReceiveDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_IPADDRESS4,m_IPAddress_MultiCastIP); DDX_Radio(pDX, IDC_RADIO_L, m_iVideoSrc); } BEGIN_MESSAGE_MAP(CMulticastSocketReceiveDlg, CDialogEx) ON_BN_CLICKED(IDC_BTN_MULTISOCKET_CONNECT, &CMulticastSocketReceiveDlg::OnBnClickedBtnMultisocketConnect) ON_BN_CLICKED(IDC_BTN_MULTISOCKET_DISCONNECT, &CMulticastSocketReceiveDlg::OnBnClickedBtnMultisocketDisconnect) ON_MESSAGE(WN_SHOW_CH96_FJDATA, &CMulticastSocketReceiveDlg::ShowCH96FJData) ON_BN_CLICKED(IDC_CHECK1, &CMulticastSocketReceiveDlg::OnBnClickedCheck1) ON_BN_CLICKED(IDC_RADIO_L, &CMulticastSocketReceiveDlg::OnRadioBtnVideoSrcClicked) ON_BN_CLICKED(IDC_RADIO_SAC1, &CMulticastSocketReceiveDlg::OnRadioBtnVideoSrcClicked) ON_BN_CLICKED(IDC_RADIO_SAC2, &CMulticastSocketReceiveDlg::OnRadioBtnVideoSrcClicked) END_MESSAGE_MAP() BOOL CMulticastSocketReceiveDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 获取窗口句柄 g_MulticastSocketReceiveDlgHwnd = GetSafeHwnd(); // 获取主机本地IP并显示 //CString str_LocalIP_Receive; GetHostAddress(str_LocalIP_ReceiveMUDP); GetDlgItem(IDC_EDIT_LOCALIP_RECEIVE)->SetWindowText(str_LocalIP_ReceiveMUDP); // 设置界面初始显示内容 m_IPAddress_MultiCastIP.SetWindowText(str_MulticastSocketIP); GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->SetWindowText("8080"); GetDlgItem(IDC_EDIT_LOCALPORT_RECEIVE)->SetWindowTextA("8082"); GetDlgItem(IDC_EDIT_MULTICASTSOCKETINFORECEIVE)->SetWindowText(str_MulticastSocketInfoReceive); // 设置按钮状态 GetDlgItem(IDC_BTN_MULTISOCKET_CONNECT)->EnableWindow(TRUE); m_strServerPayLoadIPSend = _T("123.57.54.1"); m_nServerSendLocalPort = 60302; m_nServerSendObjectPort = 11302; return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } // 连接 void CMulticastSocketReceiveDlg::OnBnClickedBtnMultisocketConnect() { UpdateData(TRUE); switch(m_iVideoSrc) { case 0: //L测控 任管数据 { //更改IP地址和端口号 m_IPAddress_MultiCastIP.GetWindowText(m_strLLinkMultiCastIP); //L测控组播IP str_MulticastSocketIP = m_strLLinkMultiCastIP; CString _str; GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->GetWindowText(_str); //从文本框中读取远端端口 m_nLLinkMulticastPort = _ttoi(_str); m_MulticastSocketPortFH96Data = m_nLLinkMulticastPort; // 创建组播接收实例——图像和复接数据 CreateMulticastSocketFH96Data(); } break; case 1: //卫通UDP单播 任管数据 { //更改IP地址和端口号 m_IPAddress_MultiCastIP.GetWindowTextA(m_strSACUDPIPAddr); //卫通UDP单播远端地址 CString _str; GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->GetWindowTextA(_str); //从文本框中读取远端端口 m_nSACUDPRemotePort = _ttoi(_str); GetDlgItem(IDC_EDIT_LOCALPORT_RECEIVE)->GetWindowTextA(_str); //从文本框中读取本地端口 m_nSACUDPLocalPort = _ttoi(_str); //创建UDP接收实例——图像和复接数据 CreateUDPSocketReceiveData(); } break; case 2: //卫通组播 光电吊舱裸流数据 { //更改IP地址和端口号 m_IPAddress_MultiCastIP.GetWindowText(m_strSACMulticastIPAddr); str_MulticastSocketIP = m_strSACMulticastIPAddr; CString _str; GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->GetWindowText(_str); //从文本框中读取远端端口 m_nSACMulticastRemotePort = _ttoi(_str); m_MulticastSocketPortFH96Data = m_nSACMulticastRemotePort; // 创建组播接收实例——图像裸流H264 CreateMulticastSocketFH96Data(); } break; default: break; } // 更改按钮状态 GetDlgItem(IDC_BTN_MULTISOCKET_CONNECT)->EnableWindow(FALSE); GetDlgItem(IDC_BTN_MULTISOCKET_DISCONNECT)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO_L)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_SAC1)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_SAC2)->EnableWindow(FALSE); //UDP服务器传输 g_UDPTrans2Server.SetCallBack(NULL, this); CString strLocalIPAddr = _T("0.0.0.0"); g_UDPTrans2Server.SetParams(strLocalIPAddr, m_nServerSendLocalPort, m_strServerPayLoadIPSend, m_nServerSendObjectPort); if (g_UDPTrans2Server.StartListening()) { g_udpStarted = true; CString strPassword = _T("FP-WRJ-98"); g_UDPTrans2Server.WriteBuffer((BYTE*)strPassword.GetBuffer(), strPassword.GetLength()); } else { g_udpStarted = false; } } // 显示CH96FJ数据内容 LRESULT CMulticastSocketReceiveDlg::ShowCH96FJData(WPARAM wParam, LPARAM lParam) { if (m_bFJDataShow == TRUE) { // 显示FJ数据150字节内容 BYTE _FJData[150]; WaitForSingleObject(g_hMutex_SaveFJData, INFINITE); memcpy(_FJData, &g_CH96FJData, 150); ReleaseMutex(g_hMutex_SaveFJData); CString _strByte; _strByte = ""; CString _strFJDataShow; _strFJDataShow = ""; for (int i = 0; i < 150; i++) { _strByte.Format("%02X",_FJData[i]); _strFJDataShow = _strFJDataShow + _strByte + "\t"; if ( 0 == (i+1)%8 ) { _strFJDataShow += "\r\n"; } } GetDlgItem(IDC_EDIT_FJDATASHOW)->SetWindowText(_strFJDataShow); } return 0; } // 创建组播连接 void CMulticastSocketReceiveDlg::CreateMulticastSocketFH96Data() { if (g_socketFH96Data != INVALID_SOCKET) { // 关闭套接字 closesocket(g_socketFH96Data); g_socketFH96Data = -1; } // 创建套接字 SetUpWinSocketFH96Data(); } // 创建WinSocket套接字 void CMulticastSocketReceiveDlg::SetUpWinSocketFH96Data() { // 加载套接字库 WSADATA WSAData; WSAStartup(WINSOCK_VERSION, &WSAData); // 创建套接字 g_socketFH96Data = socket(AF_INET, // 地址族 SOCK_DGRAM, // socket 类型 IPPROTO_UDP); // 协议 if (g_socketFH96Data == INVALID_SOCKET) { CString receiverData = "数据组播接收套接字创建失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); return; } int ret = 0; // 绑定套接字 sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(m_MulticastSocketPortFH96Data); local.sin_addr.s_addr = INADDR_ANY; ret = ::bind(g_socketFH96Data, (struct sockaddr*)&local, sizeof(local)); if(ret == SOCKET_ERROR) { CString receiverData = "数据组播接收套接字绑定port失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); return; } // 设置接收缓冲区大小 int length = 512000 ; ret = setsockopt(g_socketFH96Data,SOL_SOCKET,SO_RCVBUF,(const char*)&length, sizeof(int)); if (ret == SOCKET_ERROR) { CString receiverData = "数据组播接收套接字缓冲区设置失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); return; } int nNetTimeout = 1000; // 1S 设置接收时限 ret = setsockopt(g_socketFH96Data,SOL_SOCKET,SO_RCVTIMEO,(const char*)&nNetTimeout, sizeof(int)); if (ret == SOCKET_ERROR) { CString receiverData = "数据组播接收套接字时限设置失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); return; } struct ip_mreq mcast_addr; mcast_addr.imr_multiaddr.s_addr = inet_addr(str_MulticastSocketIP); mcast_addr.imr_interface.s_addr = INADDR_ANY; ret = setsockopt(g_socketFH96Data, IPPROTO_IP,IP_ADD_MEMBERSHIP, (char*)&mcast_addr, sizeof(mcast_addr)); if (ret == SOCKET_ERROR) { CString receiverData = "数据组播接收套接字绑定IP失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); return; } else { CString receiverData = "数据组播接收创建成功!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); switch(m_iVideoSrc) { case 0: //L测控组播 // 创建一个线程并立即执行 m_hThread_GetFH96DataFromNet = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetFH96DataFromNet, nullptr, // 传递参数 0, // 线程创建后会被马上调用 &m_ThreadID_GetFH96DataFromNet); break; case 1: //卫通UDP单播 break; case 2: //卫通组播 // 创建一个线程并立即执行 m_hThread_GetFH96DataFromNet = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetH264VideoDataFromNet, nullptr, // 传递参数 0, // 线程创建后会被马上调用 &m_ThreadID_GetFH96DataFromNet); break; default: break; } } } void CMulticastSocketReceiveDlg::ShowMulticastSocketInfoReceive() { GetDlgItem(IDC_EDIT_MULTICASTSOCKETINFORECEIVE)->SetWindowText(str_MulticastSocketInfoReceive); GetDlgItem(IDC_EDIT_MULTICASTSOCKETINFORECEIVE)->SendMessage(WM_VSCROLL,SB_BOTTOM,0); } // 获取主机IP void CMulticastSocketReceiveDlg::GetHostAddress(CString &strIP) { char HostName[100]; gethostname(HostName, sizeof(HostName)); // 获取主机名称 hostent* hn; hn = gethostbyname(HostName); // 根据主机名称得到本机IP strIP = inet_ntoa(*(struct in_addr *)hn->h_addr_list[0]); } void CMulticastSocketReceiveDlg::OnBnClickedBtnMultisocketDisconnect() { // 关闭组播 // 关闭套接字 if (INVALID_SOCKET != g_socketFH96Data) { closesocket(g_socketFH96Data); g_socketFH96Data = -1; // 卸载socket库 WSACleanup(); } //关闭卫通UDP单播 m_nSACUDPSocket.SetCallBack(NULL, nullptr); m_nSACUDPSocket.StopListening(); g_udpStarted = false; g_UDPTrans2Server.SetCallBack(NULL, nullptr); g_UDPTrans2Server.StopListening(); if (NULL != m_hThread_GetFH96DataFromNet) { TerminateThread(m_hThread_GetFH96DataFromNet, 0); m_hThread_GetFH96DataFromNet = NULL; m_ThreadID_GetFH96DataFromNet = 0; } // 更新显示内容 str_MulticastSocketInfoReceive = str_MulticastSocketInfoReceive + "数据接收已断开!\r\n" + "等待通信连接……\r\n"; ShowMulticastSocketInfo(); // 更改按钮状态 // 设置按钮状态 GetDlgItem(IDC_BTN_MULTISOCKET_CONNECT)->EnableWindow(TRUE); GetDlgItem(IDC_BTN_MULTISOCKET_DISCONNECT)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_L)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO_SAC1)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO_SAC2)->EnableWindow(TRUE); } void CMulticastSocketReceiveDlg::ShowMulticastSocketInfo() { GetDlgItem(IDC_EDIT_MULTICASTSOCKETINFORECEIVE)->SetWindowText(str_MulticastSocketInfoReceive); GetDlgItem(IDC_EDIT_MULTICASTSOCKETINFORECEIVE)->SendMessage(WM_VSCROLL,SB_BOTTOM,0); } void CMulticastSocketReceiveDlg::OnBnClickedCheck1() { m_bFJDataShow = !m_bFJDataShow; } // 键盘/鼠标消息响应函数 BOOL CMulticastSocketReceiveDlg::PreTranslateMessage(MSG* pMsg) { // 键盘消息 if (pMsg->message == WM_KEYDOWN) { // 忽略ESC和回车键 if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN) { return TRUE; } // F3键控制“组播收数”窗口的现实/隐藏 if (pMsg->wParam == VK_F3) { // 关闭窗口 OnOK(); } } return CDialogEx::PreTranslateMessage(pMsg); } void CMulticastSocketReceiveDlg::OnRadioBtnVideoSrcClicked() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); if (0 == m_iVideoSrc)//L链路SPI输出 UDP组播 { // 显示主机本地IP GetDlgItem(IDC_EDIT_LOCALIP_RECEIVE)->SetWindowText(str_LocalIP_ReceiveMUDP); // 设置界面初始显示内容 m_IPAddress_MultiCastIP.SetWindowText(str_MulticastSocketIP); GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->SetWindowText("8080"); GetDlgItem(IDC_EDIT_LOCALPORT_RECEIVE)->SetWindowTextA("8082"); }else if (1 == m_iVideoSrc)//卫通视频管理计算机网口输出 UDP单播 { // 获取主机本地IP并显示 CString str_LocalIP_Receive; str_LocalIP_Receive = _T("192.168.0.4"); GetDlgItem(IDC_EDIT_LOCALIP_RECEIVE)->SetWindowText(str_LocalIP_Receive); // 设置界面初始显示内容 CString str_RemoteIP_Connect; str_RemoteIP_Connect = _T("192.168.0.180"); m_IPAddress_MultiCastIP.SetWindowText(str_RemoteIP_Connect); GetDlgItem(IDC_EDIT_MULTISOCKETPORT_RECEIVE)->SetWindowText("8080"); GetDlgItem(IDC_EDIT_LOCALPORT_RECEIVE)->SetWindowTextA("8080"); } } void CMulticastSocketReceiveDlg::CreateUDPSocketReceiveData() { //卫通UDP连接 m_nSACUDPSocket.SetCallBack(OnReadFromUDPSACKU, this); CString strLocalIPAddr = _T("192.168.0.4"); m_nSACUDPSocket.SetParams(strLocalIPAddr, m_nSACUDPLocalPort, m_strSACUDPIPAddr, m_nSACUDPRemotePort); if (m_nSACUDPSocket.StartListening()) { CString receiverData = "任管数据接收设置成功!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); } else { CString receiverData = "任管数据接收设置失败!"; receiverData += "\r\n"; str_MulticastSocketInfoReceive += receiverData; // 显示信息 ShowMulticastSocketInfoReceive(); } }