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

📄 clientdlg.cpp

📁 网络实验网络实验网络实验网络实验网络实验
💻 CPP
字号:
// clientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "client.h"
#include "ConfigDlg.h"
#include "clientDlg.h"


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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientDlg dialog

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

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClientDlg)
	DDX_Text(pDX, IDC_SHOWTEXT_EDIT, m_sShowText);
	DDX_Text(pDX, IDC_SERVERIP_EDIT, m_sServerIp);
	DDX_Text(pDX, IDC_SERVERPORT_EDIT, m_sServerPort);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
	//{{AFX_MSG_MAP(CClientDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_CONTOSER_BUTTON, OnContoserButton)
	ON_BN_CLICKED(IDC_CONFIG_BUTTON, OnConfigButton)
	ON_BN_CLICKED(IDC_SENDER_BUTTON, OnSenderButton)
	ON_BN_CLICKED(IDC_END_BUTTON, OnEndButton)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientDlg message handlers

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

//连接到服务器
void CClientDlg::OnContoserButton() 
{
	// TODO: Add your control notification handler code here
	unsigned short port;//端口
	CString addstr;
	int ret;
	WSADATA wsaData;

	if (WSAStartup(0x101,&wsaData))
		AfxMessageBox("WSAStartup error! \n");

	cli_sock=socket(AF_INET,SOCK_STREAM,0);

	if (cli_sock==INVALID_SOCKET)
	{
		AfxMessageBox("Socket() error!\n");return;
	}

    //从编辑框得到用户的数据
    GetDlgItem(IDC_SERVERPORT_EDIT)->GetWindowText(m_sServerPort);
	port=atoi(m_sServerPort);//字符串转换成整形
	
	GetDlgItem(IDC_SERVERIP_EDIT)->GetWindowText(m_sServerIp);

	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(port);

	seraddr.sin_addr.S_un.S_addr=inet_addr(m_sServerIp);
	
	ret=connect(cli_sock,(struct sockaddr *)&seraddr,sizeof(seraddr));


    if (ret==SOCKET_ERROR)
	{
		AfxMessageBox("Connect to server error!\n Please input correct IP and PORT!\n");
	}	
	else 
	{
		addstr+="Connect server sucessfully!\n";
        Write_to_ShowText(addstr);
	}		
}


//将要显示的信息写入显示框中
void CClientDlg::Write_to_ShowText(CString adds)
{
	CEdit *output=NULL;
	m_sShowText+=adds;
	m_sShowText+="\r\n";
	GetDlgItem(IDC_SHOWTEXT_EDIT)->SetWindowText(m_sShowText);
    output=(CEdit*)GetDlgItem(IDC_SHOWTEXT_EDIT);
	            //跟踪滚动条的位置
	output->LineScroll(output->GetLineCount ());
	return;
}

//设置链路参数
void CClientDlg::OnConfigButton() 
{
	// TODO: Add your control notification handler code here
	CConfigDlg configDlg;

    configDlg.DoModal();
    
	ilost_percent=configDlg.ilost;
	iwrong_percent=configDlg.iwrong;
	timeout_interval=configDlg.itimeout;
	repeatnum=configDlg.irepeatnumber;
	windowsize=configDlg.iwinsize;
	
}

//发送端的工作程序
void CClientDlg::OnSenderButton() 
{
	// TODO: Add your control notification handler code here
	CString tempstr,addstr;
	seq_nr next_frame_to_send;
	seq_nr ack_expected;
	frame s,r;
	packet buffer;
	event_type event;
	int recvnum,j;
	Cprotocol Pro_slidingwindow;
	bool control=true;
	j=0; 
	int send_num[MAX_SEQ+1];
    CString checkstring;

	//fd_set readfds,writefds;
	 int temptime;

	for(int i=0;i<(MAX_SEQ+1);i++) 
		send_num[i]=0;
	SYSTEMTIME st;

	   RecvQueue rq;//接收数据的缓冲区
	   rq.recvbuffer=(Recvbuffer *) malloc((MAX_SEQ+1)*sizeof(Recvbuffer));//初始化
	   rq.rfront=rq.rrear=0;

	   SendQueue sq;//发送数据的缓冲区
	   sq.sendbuffer=(Sendbuffer *) malloc((MAX_SEQ+1)*sizeof(Sendbuffer));
	   sq.sfront=sq.srear=0;
	   sq.sendbuffer[sq.srear].time=0;
	   while((sq.srear+1)%(MAX_SEQ+1)!=sq.sfront)
	   {
		  sq.srear=(sq.srear+1)%(MAX_SEQ+1);
          sq.sendbuffer[sq.srear].time=0;
	   }

       sq.sfront=sq.srear=0;
	   next_frame_to_send=0;//初始化发送状态变量
	   ack_expected=1;

	    
  do
   {
	    addstr="___________________________";
        Write_to_ShowText(addstr);

	    Pro_slidingwindow.wait_for_event(cli_sock,event);

		if(event==can_write)
		{   
		     
	       if(((sq.srear-sq.sfront+MAX_SEQ+1)%(MAX_SEQ+1))<windowsize)
		   {  
			   checkstring=Pro_slidingwindow.check_network_layer();
               if(checkstring=='Y'||checkstring=='y')
			   {
			  
					Pro_slidingwindow.from_network_layer(&buffer);
			        s.kind=data;
		            s.seq=next_frame_to_send;		        
		            s.info=buffer;  
		            s.checksum=Pro_slidingwindow.checksum_mat(s.kind,s.seq,s.info);
                    
                       //要发送的帧
	                addstr="the data that will be send:";
                    Write_to_ShowText(addstr);
                    addstr=s.info.data;
                    Write_to_ShowText(addstr);
	                //要发送的帧的序号
	                addstr="发送的序号是:";
	                Write_to_ShowText(addstr);
	                addstr.Format("%d",s.seq);
	                Write_to_ShowText(addstr);
				  
			        GetSystemTime(&st);
                    //把发送的数据放到发送缓冲区
                    sq.sendbuffer[sq.srear].isack=false;
	                sq.sendbuffer[sq.srear].sendframe=s;
	                sq.sendbuffer[sq.srear].time=st.wSecond;
	                printf("the time is %d\n",sq.sendbuffer[sq.srear].time);
	                sq.srear=(sq.srear+1)%(MAX_SEQ+1);
			        inc(next_frame_to_send);
			        Pro_slidingwindow.to_physical_layer(cli_sock,s,iwrong_percent,ilost_percent);
					send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
			   }
			
			   if(checkstring=='1')
			   {
					addstr="the sender has send the data successfully!And will be disconnect with server!!\n";
					Write_to_ShowText(addstr);
                    control=false;
					break;
			   }
			   
		   }
		}
	       
      if (event==frame_arrival) 
	  {   
			 addstr="有数据到达!\n";
			 Write_to_ShowText(addstr);

			 recvnum=Pro_slidingwindow.from_physical_layer(cli_sock,r);

             if(recvnum==-1) //检查对方是否工作正常
			 {   
				addstr="the receiver has closed! Data send will be STOP!";
				Write_to_ShowText(addstr);
				break;
			 }

             if ((rq.rrear+1)%(MAX_SEQ+1)==rq.rfront)//队列已满
			 {
				 addstr="the recvbuffer is full!\n";
				 Write_to_ShowText(addstr);
			 }

			 rq.recvbuffer[rq.rrear].recvframe=r;
			 rq.recvbuffer[rq.rrear].ischeck=false;
			 rq.rrear=(rq.rrear+1)%(MAX_SEQ+1);

			 addstr.Format("the recvive buffer is %d\n",(rq.rrear-rq.rfront+MAX_SEQ+1)%(MAX_SEQ+1));
			 Write_to_ShowText(addstr);

		   //处理收到的各帧  
		    while((rq.rfront!=rq.rrear)&&(!rq.recvbuffer[rq.rfront].ischeck))
			{   
			    if(rq.recvbuffer[rq.rfront].recvframe.ack==ack_expected)
				{ 				     
				    addstr="A ACK arrival!\n";
					Write_to_ShowText(addstr);

				    addstr.Format("The number of the ACK is:%d\n",rq.recvbuffer[rq.rfront].recvframe.ack);
                    Write_to_ShowText(addstr);

                    rq.recvbuffer[rq.rfront].ischeck=true;
				    sq.sendbuffer[sq.sfront].isack=true;
				    sq.sendbuffer[sq.sfront].time=0;  //收到确认帧后,计时器停止计时
                    inc(ack_expected);
					send_num[sq.sendbuffer[sq.sfront].sendframe.seq]=0;
				    rq.rfront=(rq.rfront+1)%(MAX_SEQ+1);
					sq.sfront=(sq.sfront+1)%(MAX_SEQ+1);
					
				}
			    else
				{
				  addstr.Format("the ack we received is %d\n",rq.recvbuffer[rq.rfront].recvframe.ack);
				  Write_to_ShowText(addstr);
				  //send_num[sq.sendbuffer[sq.sfront].sendframe.seq]=0;
				  rq.rfront=(rq.rfront+1)%(MAX_SEQ+1);
				  //send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
				}
			 } 
	  }

                    
	  //处理发生超时的帧
	  GetSystemTime(&st);
	  temptime=st.wSecond;

	   if(sq.sendbuffer[sq.sfront].time>temptime)
	   {
	   temptime=temptime+60;
	   }

	if((temptime-sq.sendbuffer[sq.sfront].time)>timeout_interval&&(sq.sendbuffer[sq.sfront].time!=0))
	{
		 addstr.Format("the %d occur time out event\n",sq.sendbuffer[sq.sfront].sendframe.seq);
		 Write_to_ShowText(addstr);

		 //计时器置为0
		 sq.stemp=sq.sfront;
		 while(sq.stemp!=sq.srear)
		{
			sq.sendbuffer[sq.stemp].time=0;
			sq.stemp=(sq.stemp+1)%(MAX_SEQ+1);
		}

		 if(send_num[sq.sendbuffer[sq.sfront].sendframe.seq]>repeatnum)
			 {
                addstr.Format("the send_num is bigger than repeatnum! The data send will be stop!\n");
				Write_to_ShowText(addstr);

				shutdown(cli_sock,1);
			    break;
			 }
	      //超时重传数据
         sq.stemp=sq.sfront;
		 ack_expected=sq.sendbuffer[sq.sfront].sendframe.seq;////
		 inc(ack_expected);////
		 while(sq.stemp!=sq.srear)
		 {  
			 send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
             GetSystemTime(&st);
			 sq.sendbuffer[sq.stemp].time=st.wSecond;
			 addstr="resend data! the read time!\n";
			 Write_to_ShowText(addstr);

              //要发送的帧
	         addstr="the data that will be send:";
             Write_to_ShowText(addstr);

             addstr=sq.sendbuffer[sq.stemp].sendframe.info.data;
             Write_to_ShowText(addstr);

	         //要发送的帧的序号
	         addstr="发送的序号是:";
	         Write_to_ShowText(addstr);
	         addstr.Format("%d",sq.sendbuffer[sq.stemp].sendframe.seq);
	         Write_to_ShowText(addstr);

			 Pro_slidingwindow.to_physical_layer(cli_sock,sq.sendbuffer[sq.stemp].sendframe,iwrong_percent,ilost_percent);
             sq.stemp=(sq.stemp+1)%(MAX_SEQ+1); 
		 }
	}
   }while(control);


	shutdown(cli_sock,0);
	
}

//关闭窗口
void CClientDlg::OnEndButton() 
{
	// TODO: Add your control notification handler code here
    closesocket(cli_sock);
	CDialog::OnOK();
}

⌨️ 快捷键说明

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