📄 tcptestdlg.cpp
字号:
// tcptestDlg.cpp : implementation file
//
#include "stdafx.h"
#include "tcptest.h"
#include "tcptestDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define FRM_LEN 10
#define PORT_NO 2403
#define WM_RESFRESH_DATA (WM_USER + 99)
CTcptestDlg *g_pTcpDlg = NULL;
SOCKET data_socket;
DWORD dwIPAddr;
int g_iLinkState = 0;
DWORD g_dwSendBytes = 0;
DWORD g_dwRecvBytes = 0;
UINT TcpCliThread();
SOCKET Connect(DWORD srv_ip);
void CloseConnect(SOCKET sock);
int socksend(SOCKET sock, char* pBuff, int BuffLen);
int sockrecv(SOCKET sock, char* buffer);
/////////////////////////////////////////////////////////////////////////////
// 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()
/////////////////////////////////////////////////////////////////////////////
// CTcptestDlg dialog
CTcptestDlg::CTcptestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTcptestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTcptestDlg)
m_strState = _T("");
m_dwSendBytes = 0;
m_dwRecvBytes = 0;
m_dwErrBytes = 0;
m_fErrRate = 0.0f;
m_nCycle = 100;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTcptestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTcptestDlg)
DDX_Control(pDX, IDC_SPIN1, m_spin);
DDX_Control(pDX, IDC_LIST_RECV, m_ListRecv);
DDX_Control(pDX, IDC_LIST_SEND, m_ListSend);
DDX_Control(pDX, IDC_IPADDRESS_STATION, m_srv_ip);
DDX_Text(pDX, IDC_STATE, m_strState);
DDX_Text(pDX, IDC_EDIT_SEND, m_dwSendBytes);
DDX_Text(pDX, IDC_EDIT_RECV, m_dwRecvBytes);
DDX_Text(pDX, IDC_EDIT_ERR, m_dwErrBytes);
DDX_Text(pDX, IDC_EDIT_RATE, m_fErrRate);
DDX_Text(pDX, IDC_EDIT_CYCLE, m_nCycle);
DDV_MinMaxUInt(pDX, m_nCycle, 10, 2000);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTcptestDlg, CDialog)
//{{AFX_MSG_MAP(CTcptestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_SERIAL, OnButtonSerial)
ON_BN_CLICKED(IDC_BUTTON_CONNECT, OnButtonConnect)
ON_BN_CLICKED(IDC_BUTTON_DISCONNECT, OnButtonDisconnect)
ON_BN_CLICKED(IDC_BUTTON_AUTOSEND, OnButtonAutosend)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_RESFRESH_DATA, OnRefreshData)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTcptestDlg message handlers
BOOL CTcptestDlg::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
m_bSerial = FALSE;
m_spin.SetRange(10, 2000);
InitializeCriticalSection(&sync_obj);
g_pTcpDlg = this;
DWORD dwid;
hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)TcpCliThread, 0, CREATE_SUSPENDED, &dwid);
return TRUE; // return TRUE unless you set the focus to a control
}
void CTcptestDlg::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 CTcptestDlg::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 CTcptestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTcptestDlg::OnButtonSerial()
{
// m_bSerial = !m_bSerial;
// if(m_bSerial)
// {
EnterCriticalSection(&sync_obj);
UpdateData(TRUE);
TRACE("begin send %d, recv %d\n", g_dwSendBytes, g_dwRecvBytes);
g_dwSendBytes = (g_dwSendBytes - g_dwRecvBytes) + g_dwRecvBytes*10;
g_dwRecvBytes *= 10;
m_dwRecvBytes = g_dwRecvBytes;
m_dwSendBytes = g_dwSendBytes;
TRACE("end send %d, recv %d\n", g_dwSendBytes, g_dwRecvBytes);
UpdateData(FALSE);
LeaveCriticalSection(&sync_obj);
// m_dwErrBytes*=10;
// GetDlgItem(IDC_BUTTON_SERIAL)->SetWindowText("网络");
// }
// else
// {
// m_dwSendBytes/=10;
// m_dwRecvBytes/=10;
// m_dwErrBytes/=10;
// GetDlgItem(IDC_BUTTON_SERIAL)->SetWindowText("串口");
// }
}
void CTcptestDlg::OnButtonConnect()
{
UpdateData(TRUE);
m_srv_ip.GetAddress(dwIPAddr);
data_socket = Connect(dwIPAddr);
if(data_socket == INVALID_SOCKET)
{
g_iLinkState = 0;
m_strState = "未连接";
}
else
{
g_iLinkState = 1;
m_strState = "已连接";
m_dwSendBytes = 0;
m_dwRecvBytes = 0;
m_dwErrBytes = 0;
m_fErrRate = 0.0f;
m_nCycle = 100;
g_dwSendBytes = 0;
g_dwRecvBytes = 0;
m_ListRecv.ResetContent();
m_ListSend.ResetContent();
GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_AUTOSEND)->EnableWindow(TRUE);
}
UpdateData(FALSE);
}
void CTcptestDlg::OnButtonDisconnect()
{
SuspendThread(hThread);
CloseConnect(data_socket);
g_iLinkState = 0;
m_strState = "未连接";
GetDlgItem(IDC_BUTTON_CONNECT)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_DISCONNECT)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_AUTOSEND)->EnableWindow(FALSE);
UpdateData(FALSE);
}
void CTcptestDlg::OnButtonAutosend()
{
if (data_socket != INVALID_SOCKET)
{
ResumeThread(hThread);
}
}
LRESULT CTcptestDlg::OnRefreshData(WPARAM wParam, LPARAM lParam)
{
EnterCriticalSection(&sync_obj);
UpdateData(TRUE);
// m_dwSendBytes += 10;
// m_dwRecvBytes += 10;
m_dwSendBytes = g_dwSendBytes;
m_dwRecvBytes = g_dwRecvBytes;
m_dwErrBytes = 0;
m_fErrRate = 0;
UpdateData(FALSE);
LeaveCriticalSection(&sync_obj);
return 0;
}
void CTcptestDlg::OnClose()
{
ResumeThread(hThread);
CloseConnect(data_socket);
DeleteCriticalSection(&sync_obj);
CDialog::OnClose();
}
UINT TcpCliThread()
{
int ret, send_ret;
int nCount = 0;
CTcptestDlg* pTcpDlg = g_pTcpDlg;
srand( (unsigned)time( NULL ) );
for(;;)
{
char sbuf[FRM_LEN] = {0};
char rbuf[FRM_LEN] = {0};
if (g_iLinkState == 0)
{
data_socket = Connect(dwIPAddr);
if(data_socket != INVALID_SOCKET)
g_iLinkState = 1;
}
if (g_iLinkState == 1)
{
int n;
for (n=0; n<FRM_LEN; n++)
{
sbuf[n] = rand() % 256;
}
SOCKET work_sock = data_socket;
send_ret = socksend(work_sock, sbuf, 10);
ret = 0;
if (send_ret>0)
{
TRACE("send num %d\n", send_ret);
CString strSend;
CString strRecv;
CString strTmp;
for (n=0; n<FRM_LEN; n++)
{
strTmp.Format("%02X ", (BYTE)sbuf[n]);
strSend += strTmp;
}
pTcpDlg->m_ListSend.AddString(strSend);
pTcpDlg->m_ListSend.SetTopIndex(pTcpDlg->m_ListSend.GetCount()-1);
g_dwSendBytes += 10;
ret = sockrecv(work_sock, rbuf);
EnterCriticalSection(&(pTcpDlg->sync_obj));
if(ret > 0)
{
pTcpDlg->m_ListRecv.AddString(strSend);
pTcpDlg->m_ListRecv.SetTopIndex(pTcpDlg->m_ListRecv.GetCount()-1);
g_dwRecvBytes += 10;
}
LeaveCriticalSection(&(pTcpDlg->sync_obj));
TRACE("recv num %d, send %d, recv %d\n", ret, g_dwSendBytes, g_dwRecvBytes);
if(ret <=0 )
{
// pTcpDlg->m_ListSend.AddString(strSend);
// pTcpDlg->m_ListSend.SetTopIndex(pTcpDlg->m_ListSend.GetCount()-1);
// g_dwSendBytes += 10;
CloseConnect(work_sock);
g_iLinkState = 0;
}
pTcpDlg->SendMessage(WM_RESFRESH_DATA, 0, 0);
nCount++;
if(nCount == 2048)
{
pTcpDlg->m_ListRecv.ResetContent();
pTcpDlg->m_ListSend.ResetContent();
nCount = 0;
}
}
else
{
CloseConnect(work_sock);
g_iLinkState = 0;
}
}
Sleep(pTcpDlg->m_nCycle);
}
return 0;
}
SOCKET Connect(DWORD srv_ip)
{
SOCKET sock_ret;
int len;
struct sockaddr_in des;
SOCKET sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
return INVALID_SOCKET;
}
des.sin_family = PF_INET;
des.sin_addr.s_addr = htonl(srv_ip);
des.sin_port = htons(PORT_NO);
len = sizeof(struct sockaddr_in);
u_long argp=1;
ioctlsocket(sock, FIONBIO, &argp);
if(connect(sock, (struct sockaddr *)&des, len)!=0)
{
int err = WSAGetLastError();
if( err == WSAEWOULDBLOCK )
{
timeval timeout;
timeout.tv_sec=3;
timeout.tv_usec=0;
fd_set rset,wset;
FD_ZERO(&rset);
FD_ZERO(&wset);
int data_sock = sock;
if(data_sock<0){
shutdown(sock, 2);
closesocket(sock);
return INVALID_SOCKET;
}
FD_SET(data_sock, &rset);
FD_SET(data_sock, &wset);
int nret = select(data_sock+1, &rset, &wset, 0, &timeout);
if(nret>0)
{
if( FD_ISSET(data_sock,&rset) || FD_ISSET(data_sock,&wset) )
{
int error = 0;
int len = sizeof(error);
if( ( getsockopt(data_sock,SOL_SOCKET,SO_ERROR,(char*)&error,&len)>=0 ) && (!error) )
sock_ret = sock;
else
sock_ret = INVALID_SOCKET;
}
else
sock_ret = INVALID_SOCKET;
}
else
{
sock_ret = INVALID_SOCKET;
}
}
else
{
sock_ret = INVALID_SOCKET;
}
}
else
sock_ret = sock;
if(sock_ret != INVALID_SOCKET)
{
}
else
{
shutdown(sock, 2);
closesocket(sock);
}
return (sock_ret);
}
void CloseConnect(SOCKET sock)
{
shutdown(sock,2);
closesocket(sock);
return ;
}
//向子站发送数据
int socksend(SOCKET sock, char* pBuff, int BuffLen)
{
char* buff = pBuff;
int len = BuffLen;
int val = 0;
timeval timeout;
timeout.tv_sec=0;
timeout.tv_usec=0;
int nret;
fd_set set;
SOCKET s = sock;
FD_ZERO(&set);
FD_SET(s, &set);
nret = select(0, 0, &set, 0, &timeout);
if(nret==0)
{
return -1;//缓冲区已满
}
else if(nret==SOCKET_ERROR)
{
return -1;//错误
}
val = send(sock,(char *)buff, len, 0);
return val;
}
int sockrecv(SOCKET sock, char* buffer)
{
char* pbuff = buffer;
int recvNum = 0;
int nret;
fd_set set;
SOCKET s = sock;
FD_ZERO(&set);
FD_SET(s, &set);
int recv_delay_time = 1200;
timeval tv;
tv.tv_sec = recv_delay_time/1000;
tv.tv_usec = recv_delay_time%1000;
nret = select(s + 1, &set, 0, 0, &tv);
if(nret==0)
{
return -2;//overtime
}
else if(nret==SOCKET_ERROR)
{
return -1;//socket error
}
recvNum = recv(s, pbuff, FRM_LEN, 0);
if(recvNum==SOCKET_ERROR || recvNum==0)
{
CloseConnect(0);
return 0;
}
return recvNum;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -