📄 clientdlg.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 + -