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

📄 remotesimdlg.cpp

📁 此文件包含两个独立程序,Sender和Receiver,用于测试网络对RAW类型的IP包的传输
💻 CPP
字号:
// RemoteSimDlg.cpp : implementation file
//

#include "stdafx.h"
#include "RemoteSim.h"
#include "RemoteSimDlg.h"
#include "process.h"

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

#define MPEG_BUFFER_SIZE 17000 /*16*1024+150*/

#define RTP_VER 2
#define RTP_PT 77
#define RTP_DELAYTHREHOLD 0xfff0

#pragma pack(push,1)
struct MPEGIPHEADER{
	unsigned char hdLen:4;
	unsigned char ver:4;
	unsigned char tos;
	unsigned short totalLen;
	unsigned short flag;
	unsigned short offset:13;
	unsigned short offsetflag:3;
	unsigned char ttl;
	unsigned char protocol;
	unsigned short crc;
	unsigned long srcAdr;
	unsigned long dstAdr;
};
struct RTPHEADERRECEIVE
{
	unsigned char cc:4;
	unsigned char p:1;
	unsigned char x:1;
	unsigned char v:2;
	unsigned char pt:7;
	unsigned char m:1;
	unsigned short sn;
	unsigned int timestamp;
	unsigned int ssrc;
};
#pragma pack(pop)

/////////////////////////////////////////////////////////////////////////////
// CRemoteSimDlg dialog
char g_filename[100];
char g_strIP[20];
char g_strIP1[20];
char g_strIP_to[20];
int g_nProtocol;

int g_PacketReceived;
unsigned long g_PacketLost;

bool g_bStarted=false;
bool g_bStop=false;

void receivethread(LPVOID lpParameter);

CRemoteSimDlg::CRemoteSimDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CRemoteSimDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CRemoteSimDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CRemoteSimDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRemoteSimDlg)
		DDX_Text(pDX, IDC_E_IPADDRESS, m_strIP);
		DDX_Text(pDX, IDC_E_IPADDRESS2, m_nProtocol);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CRemoteSimDlg, CDialog)
	//{{AFX_MSG_MAP(CRemoteSimDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_B_CONNECT, OnBnClickedBConnect)
	ON_WM_TIMER()
	ON_EN_CHANGE(IDC_E_IPADDRESS2, OnEnChangeEIpaddress2)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRemoteSimDlg message handlers

BOOL CRemoteSimDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 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
	m_strIP="225.1.1.11";
	//m_strIP1="172.96.33.132";
	//sprintf(g_filename,"test.mpg");
	sprintf(g_strIP,(LPCSTR)m_strIP);
	//sprintf(g_strIP1,(LPCSTR)m_strIP1);
	//sprintf(g_strIP_to,"225.1.1.12");
	m_nProtocol=108;
	SetTimer(100,1000,NULL);
	UpdateData(FALSE);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// 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 CRemoteSimDlg::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 CRemoteSimDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CRemoteSimDlg::OnBnClickedBConnect()
{
	UpdateData(TRUE);
	sprintf(g_strIP,(LPCSTR)m_strIP);
	g_nProtocol=m_nProtocol;
	//sprintf(g_strIP1,(LPCSTR)m_strIP1);
	GetDlgItem(IDC_B_CONNECT)->EnableWindow(FALSE);
	_beginthread(receivethread,640*1024,NULL);
}

void _cdecl receivethread(LPVOID lpParameter)
{
	char g_mpeg_pool_data[MPEG_BUFFER_SIZE];
	int err;
	//CFile file;
	
	//file.Open(g_filename,CFile::modeCreate|CFile::modeReadWrite);

	SOCKET s=socket(AF_INET,SOCK_RAW,g_nProtocol);
	//SOCKET stcp=socket(AF_INET,SOCK_STREAM,0);
	if (s==INVALID_SOCKET)
		MessageBox(NULL,"Create Mulicast error!","Loopback",MB_OK);
	//if (stcp==INVALID_SOCKET)
	//	MessageBox(NULL,"Create Mulicast error!","Loopback",MB_OK);

	struct sockaddr_in address;
	address.sin_family=AF_INET;
	address.sin_addr.s_addr=htonl(INADDR_ANY);
	address.sin_port=htons(0);

	err=bind(s,(struct sockaddr *)&address,sizeof(address));
	if (err!=0)
		MessageBox(NULL,"Bind socker error!","Loopback",MB_OK);
	//err=bind(stcp,(struct sockaddr *)&address,sizeof(address));
	//if (err!=0)
	//	MessageBox(NULL,"Bind socker error!","Loopback",MB_OK);

	
	//struct sockaddr_in to;
	struct ip_mreq mreq;
	mreq.imr_interface.S_un.S_addr=INADDR_ANY;
	mreq.imr_multiaddr.S_un.S_addr=inet_addr(g_strIP);
	
	//ZeroMemory(&to,sizeof(to));

	//to.sin_family=AF_INET;
	//to.sin_addr.s_addr=inet_addr(g_strIP1);
	//to.sin_port=htons(9099);

	//err=connect(stcp,(struct sockaddr *)&to,sizeof(to));
    //if (err!=0)
	//	MessageBox(NULL,"connect error!","Loopback",MB_OK);

	if (setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&mreq,sizeof(mreq)))
		MessageBox(NULL,"Add multicast membership error!","Loopback",MB_OK);

	//memset(&to,0,sizeof(to));
	//to.sin_family=AF_INET;
	//to.sin_addr.s_addr=inet_addr(g_strIP_to);

	int nLen;
	struct MPEGIPHEADER *pIPHeader;
	struct RTPHEADERRECEIVE *pRTPHeader;
	
	bool bFirst=true;
	unsigned short sn;
	unsigned short diff;
	unsigned long srcAdr;
	unsigned int ssrc;
    while(1)
	{
		nLen=recv(s,g_mpeg_pool_data,MPEG_BUFFER_SIZE,0);
        if (nLen==-1||nLen==0||nLen>=MPEG_BUFFER_SIZE)
			continue;
		pIPHeader=(struct MPEGIPHEADER *)g_mpeg_pool_data;
		pRTPHeader=(struct RTPHEADERRECEIVE *)(g_mpeg_pool_data+
				pIPHeader->hdLen*4);
		if (nLen!=ntohs(pIPHeader->totalLen)) continue;
		if (bFirst)
		{
			sn=ntohs(pRTPHeader->sn)-1;
			ssrc=pRTPHeader->ssrc;
			srcAdr=pIPHeader->srcAdr;
			bFirst=false;
			g_PacketLost=0;
		}
		
		if (pRTPHeader->v!=RTP_VER) continue;
		if (pRTPHeader->pt!=RTP_PT) continue;
		if (srcAdr!=pIPHeader->srcAdr) continue;
		if (ssrc!=pRTPHeader->ssrc)
		{
			bFirst=true;
			continue;
		}
		diff=ntohs(pRTPHeader->sn)-sn;
		if (diff>RTP_DELAYTHREHOLD||diff==0) continue;
		
		g_PacketReceived++;
		g_PacketLost+=diff-1;
		
		sn=ntohs(pRTPHeader->sn);
		
		//send(stcp,g_mpeg_pool_data+pIPHeader->hdLen*4+
		//	sizeof(struct RTPHEADERRECEIVE)+ntohl(pRTPHeader->cc)*4,
		//	nLen-pIPHeader->hdLen*4-sizeof(struct RTPHEADERRECEIVE)-ntohl(pRTPHeader->cc)*4,0);
		//file.Write(g_mpeg_pool_data+pIPHeader->hdLen*4+
		//	sizeof(struct RTPHEADERRECEIVE)+ntohl(pRTPHeader->cc)*4,
		//	nLen-pIPHeader->hdLen*4-sizeof(struct RTPHEADERRECEIVE)-ntohl(pRTPHeader->cc)*4);
		//sendto(s,g_mpeg_pool_data+pIPHeader->hdLen*4,nLen-pIPHeader->hdLen*4,0,
		//	(struct sockaddr *)&to,sizeof(to));
	}

	closesocket(s);
	return ;
}

void CRemoteSimDlg::OnTimer(UINT nIDEvent)
{
	if (nIDEvent==100)
	{
		sprintf(m_strTemp,"%d",g_PacketReceived);
		GetDlgItem(IDC_PACKET_RECEIVED)->SetWindowText(m_strTemp);
		sprintf(m_strTemp,"%d",g_PacketLost);
		GetDlgItem(IDC_PACKET_LOST)->SetWindowText(m_strTemp);
	}
	CDialog::OnTimer(nIDEvent);
}

void CRemoteSimDlg::OnEnChangeEIpaddress2()
{
	// TODO:  如果该控件是 RICHEDIT 控件,则它将不会
	// 发送该通知,除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask(),
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
}

⌨️ 快捷键说明

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