头文件:
// CeTcpClient.h: interface for the CCeTcpClient class.
//
//
#if !defined(AFX_CETCPCLIENT_H__B7856B99_69E7_4868_9BA3_96152245C65E__INCLUDED_)
#define AFX_CETCPCLIENT_H__B7856B99_69E7_4868_9BA3_96152245C65E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <winsock.h>
// 连接断开
typedef void (CALLBACK *ONDISCONNECT)(CWnd *);
// 数据接收
typedef void (CALLBACK *ONREAD)(CWnd *,const char *,int);
// Socket 错误
typedef void (CALLBACK *ONERROR)(CWnd *,int);
class CCeTcpClient
{
public:
CCeTcpClient();
virtual ~CCeTcpClient();
public:
// 服务器 IP 地址
CString m_csRemoteHost;
// 服务器端口
int m_iPort;
// 连接断开
ONDISCONNECT OnDisConnect;
// 接收数据
ONREAD OnRead;
// 发生错误
ONERROR OnError;
public:
// 打开 Socket
bool Open(CWnd *pWnd);
// 关闭 Socket
bool Close();
// 与服务器端建立连接
bool Connect();
// 向服务器端发送数据
bool SendData(const char *pcBuffer,int iLen);
private:
// Socket 句柄
SOCKET m_socket;
// 通讯线程退出事件
HANDLE m_hExitThreadEvent;
// 通讯线程
HANDLE m_hTcpThreadHandle;
// 父窗口句柄
CWnd *m_pOwnerWnd;
private:
// 通讯线程
static DWORD SocketControlThread(LPVOID lparam);
};
#endif // !defined(AFX_TCPCLIENT_CE_H__B7856B99_69E7_4868_9BA3_96152245C65E__INCLUDED_)
源文件:
测试代码:
BOOL CTCPClientDlg::OnInitDialog()
{
//m_bFullScreen = FALSE;
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
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// 初始化输入值
m_csRemoteHost = GetLocalIP(); // 在模拟器上测试时用: 客户端与服务器都运行在模拟器上
m_iRemotePort = 5000;
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
// 连接断开
void CALLBACK CTCPClientDlg::OnDisConnect(CWnd *pWnd)
{
CTCPClientDlg *pDlg = (CTCPClientDlg *)pWnd;
CStatic *pStatus = (CStatic *)pDlg->GetDlgItem(IDC_LBLCONNSTATUS);
ASSERT(NULL != pStatus);
pStatus->SetWindowText(L"连接断开");
CButton *pBtnConn = (CButton *)pDlg->GetDlgItem(IDC_BTNCONN);
CButton *pBtnDisConn = (CButton *)pDlg->GetDlgItem(IDC_BTNDISCONN);
CButton *pBtnSendData = (CButton *)pDlg->GetDlgItem(IDC_BTNSENDDATA);
ASSERT(NULL != pBtnConn);
ASSERT(NULL != pBtnDisConn);
ASSERT(NULL != pBtnSendData);
pBtnConn->EnableWindow(TRUE);
pBtnDisConn->EnableWindow(FALSE);
pBtnSendData->EnableWindow(FALSE);
}
// 接收的数据显示
void CALLBACK CTCPClientDlg::OnRead(CWnd *pWnd,const char *pcBuffer,int iLen)
{
CTCPClientDlg *pDlg = (CTCPClientDlg *)pWnd;
CString csRecvStr = pcBuffer;
CEdit *pEdtRecv = (CEdit *)pDlg->GetDlgItem(IDC_EDTRECV);
ASSERT(NULL != pEdtRecv);
//将接收的数据显示到接收文本框上
pEdtRecv->SetWindowText(csRecvStr);
}
// Socket 错误显示
void CALLBACK CTCPClientDlg::OnError(CWnd *pWnd,int iErrorCode)
{
CString csErrorInfo;
csErrorInfo.Format(L"%s:%d",L"客户端socket发生错误",iErrorCode);
AfxMessageBox(csErrorInfo);
}
// 建立连接
void CTCPClientDlg::OnBtnconn()
{
CStatic *pStatus = (CStatic *)GetDlgItem(IDC_LBLCONNSTATUS);
CButton *pBtnConn = (CButton *)GetDlgItem(IDC_BTNCONN);
CButton *pBtnDisConn = (CButton *)GetDlgItem(IDC_BTNDISCONN);
CButton *pBtnSendData = (CButton *)GetDlgItem(IDC_BTNSENDDATA);
ASSERT(NULL != pStatus);
ASSERT(NULL != pBtnConn);
ASSERT(NULL != pBtnDisConn);
ASSERT(NULL != pBtnSendData);
UpdateData(TRUE);
// 设置 m_tcpClient 属性
m_tcpClient.m_csRemoteHost = m_csRemoteHost;
m_tcpClient.m_iPort = m_iRemotePort;
m_tcpClient.OnDisConnect = OnDisConnect;
m_tcpClient.OnRead = OnRead;
m_tcpClient.OnError = OnError;
// 打开客户端 socket
m_tcpClient.Open(this);
// 与服务器端连接
if(m_tcpClient.Connect())
{
pStatus->SetWindowText(L"建立连接");
UpdateData(FALSE);
}
else
{
AfxMessageBox(L"建立连接失败");
pStatus->SetWindowText(L"连接断开");
return;
}
pBtnConn->EnableWindow(FALSE);
pBtnDisConn->EnableWindow(TRUE);
pBtnSendData->EnableWindow(TRUE);
}
// 断开连接
void CTCPClientDlg::OnBtndisconn()
{
if(m_tcpClient.Close())
{
CStatic *pStatus = (CStatic *)GetDlgItem(IDC_LBLCONNSTATUS);
CButton *pBtnConn =(CButton*)GetDlgItem(IDC_BTNCONN);
CButton *pBtnDisConn = (CButton*)GetDlgItem(IDC_BTNDISCONN);
CButton *pBtnSendData = (CButton*)GetDlgItem(IDC_BTNSENDDATA);
ASSERT(NULL != pStatus);
ASSERT(NULL != pBtnConn);
ASSERT(NULL != pBtnDisConn);
ASSERT(NULL != pBtnSendData);
pStatus->SetWindowText(L"连接断开");
pBtnConn->EnableWindow(TRUE);
pBtnDisConn->EnableWindow(FALSE);
pBtnSendData->EnableWindow(FALSE);
}
else
{
AfxMessageBox(L"连接断开失败");
}
}
// 发送数据
void CTCPClientDlg::OnBtnsenddata()
{
char *pcSendBuf;
int iSendLength = 0;
UpdateData(TRUE);
iSendLength = m_csSendData.GetLength();
pcSendBuf = new char[iSendLength * 2];
ASSERT(NULL != pcSendBuf);
wcstombs(pcSendBuf,m_csSendData,iSendLength);
if(!m_tcpClient.SendData(pcSendBuf,iSendLength))
{
AfxMessageBox(L"发送失败");
}
delete[] pcSendBuf;
pcSendBuf = NULL;
}