服务器:
1 在StdAfx.h中引入<winsock2.h>
2 初始化Winsock库
WSADATA wsaData; (WSDATAhttp://blog.youkuaiyun.com/liuhongwei_study/article/details/8128207)
WORD sockVersion = MAKEWORD(2, 0);
::WSAStartup(sockVersion, &wsaData);
3添加对话框
4 变量设置
5编写代码:
// TCPServerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "TCPServer.h"
#include "TCPServerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_SOCKET WM_USER + 1 // 定义网络事件通知消息
/
// 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()
/
// CTCPServerDlg dialog
CTCPServerDlg::CTCPServerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTCPServerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTCPServerDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTCPServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTCPServerDlg)
DDX_Control(pDX, IDC_DATA, m_listData);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTCPServerDlg, CDialog)
//{{AFX_MSG_MAP(CTCPServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_BN_CLICKED(IDC_START, OnStart)
ON_MESSAGE(WM_SOCKET, OnSocket)
ON_BN_CLICKED(IDC_SEND, OnSend)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CTCPServerDlg message handlers
BOOL CTCPServerDlg::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
m_bar.Create(WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP, CRect(0, 0, 0, 0), this, 101);
m_bar.SetBkColor(RGB(0xa6, 0xca, 0xf0)); // 背景色
int arWidth[] = { 200, -1 };
m_bar.SetParts(2, arWidth); // 分栏
m_bar.SetText(" 忙碌", 1, 0); // 第一个栏的文本
m_bar.SetText(" 空闲", 0, 0); // 第二个栏的文本
m_listData.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);// 设置列表视图控件的属性
m_listData.InsertColumn(0, "方向", LVCFMT_LEFT, 200);
m_listData.InsertColumn(1, "数据", LVCFMT_LEFT, 170);
m_socket = INVALID_SOCKET; // 初始化监听套节字和连接列表
m_nClient = 0;
char szHost[256];
::gethostname(szHost, 256); // 取得本机名称
HOSTENT* pHost = gethostbyname(szHost);// 通过本机名称取得地址信息
if(pHost != NULL)
{
CString sIP;
in_addr *addr =(in_addr*) *(pHost->h_addr_list); // 得到第一个IP地址
sIP.Format(" 本机IP:%s", inet_ntoa(addr[0]));// 显示给用户
m_bar.SetText(sIP, 0, 0);
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CTCPServerDlg::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 CTCPServerDlg::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 CTCPServerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
BOOL CTCPServerDlg::AddClient(SOCKET s)
{
if(m_nClient < MAX_SOCKET)
{
m_arClient[m_nClient++] = s;// 添加新的成员
return TRUE;
}
return FALSE;
}
void CTCPServerDlg::OnClear()
{
// TODO: Add your control notification handler code here
m_listData.DeleteAllItems();
}
void CTCPServerDlg::OnStart() // 开启服务
{
// TODO: Add your control notification handler code here
if(m_socket == INVALID_SOCKET)
{
CString sPort;
GetDlgItem(IDC_PORT)->GetWindowText(sPort);// 取得端口号
int nPort = atoi(sPort);
if(nPort < 1 || nPort > 65535)
{
MessageBox("端口号错误!");
return;
}
if(!CreateAndListen(nPort))// 创建监听套节字,使它进入监听状态
{
MessageBox("启动服务出错!");
return;
}
GetDlgItem(IDC_START)->SetWindowText("停止服务"); // 设置相关子窗口控件状态
m_bar.SetText(" 正在监听……", 0, 0);
GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
}
else // 停止服务
{
CloseAllSocket();// 关闭所有连接
GetDlgItem(IDC_START)->SetWindowText("开启服务");// 设置相关子窗口控件状态
m_bar.SetText(" 空闲", 0, 0);
GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
}
}
void CTCPServerDlg::OnCancel()
{
// TODO: Add extra cleanup here
CloseAllSocket();
CDialog::OnCancel();
}
void CTCPServerDlg::CloseAllSocket()
{
if(m_socket != INVALID_SOCKET)//关闭监听套接字
{
::closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
for(int i=0 ; i<m_nClient; i++)
{
::closesocket(m_arClient[i]);
}
m_nClient =0;
}
BOOL CTCPServerDlg::CreateAndListen(int nPort)
{
if(m_socket == INVALID_SOCKET)
::closesocket(m_socket);
m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建套接字
if(m_socket == INVALID_SOCKET)
return FALSE;
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.s_addr = INADDR_ANY;
if(::bind(m_socket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
return FALSE;
}
::WSAAsyncSelect(m_socket, m_hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE); // 设置socket为窗口通知消息类型
::listen(m_socket,5);// 进入监听模式
return TRUE;
}
void CTCPServerDlg::AddDataToList(SOCKET s, LPCTSTR pszText, BOOL bRecv)
{
sockaddr_in sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
::getpeername(s, (SOCKADDR*)&sockAddr, &nSockAddrLen); // 取得对方的IP地址和端口号
int nPeerPort = ::ntohs(sockAddr.sin_port);
CString sPeerIP = ::inet_ntoa(sockAddr.sin_addr);
DWORD dwIP = ::inet_addr(sPeerIP);
hostent* pHost = ::gethostbyaddr((LPSTR)&dwIP, 4, AF_INET);
char szHostName[256];
strncpy(szHostName, pHost->h_name, 256);
CString strItem;
if(bRecv)
{
strItem = "【接收】";
}
else
{
strItem = "【发送】";
}
strItem = strItem + CString(szHostName) + "["+ sPeerIP+ "] ";
int nIndex = m_listData.GetItemCount();
m_listData.InsertItem(nIndex, strItem, 0);
m_listData.SetItemText(nIndex, 1, pszText);
}
long CTCPServerDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
// 取得有事件发生的套节字句柄
SOCKET s = wParam;
// 查看是否出错
if(WSAGETSELECTERROR(lParam))
{
RemoveClient(s);
::closesocket(s);
return 0;
}
switch(WSAGETSELECTEVENT(lParam))// 处理发生的事件
{
case FD_ACCEPT: // 监听中的套接字检测到有连接进入
{
if(m_nClient < MAX_SOCKET)
{
SOCKET client = ::accept(s, NULL, NULL);// 接受连接请求,新的套节字client是新连接的套节字
int i = ::WSAAsyncSelect(client,
m_hWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE); // 设置新的套节字为窗口通知消息类型
AddClient(client);
}
else
{
MessageBox("连接客户太多!");
}
}
break;
case FD_CLOSE:// 检测到套接字对应的连接被关闭
{
RemoveClient(s);
::closesocket(s);
}
break;
case FD_READ:// 套接字接受到对方发送过来的数据包
{
char szText[1024] ={ 0 };
::recv(s,szText,1024,0);
AddDataToList(s,szText,TRUE);
SendData(s);
}
break;
}
return 0;
}
void CTCPServerDlg::RemoveClient(SOCKET s)
{
BOOL bFind = FALSE;
for(int i=0; i<m_nClient; i++)
{
if(m_arClient[i] == s)
{
bFind = TRUE;
break;
}
}
if(bFind)// 如果找到就将此成员从列表中移除
{
m_nClient--;
for(int j=i; j<m_nClient; j++) // 将此成员后面的成员都向前移动一个单位
{
m_arClient[j] = m_arClient[j+1];
}
}
}
void CTCPServerDlg::SendData(SOCKET s)
{
char szText[1024]="数据已收到";
::send(s,szText,1024,0);
AddDataToList(s,szText,FALSE);
}
void CTCPServerDlg::OnSend()
{
// TODO: Add your control notification handler code here
if(m_socket == INVALID_SOCKET)
{
return;
}
CString sText;
GetDlgItem(IDC_TEXT)->GetWindowText(sText);//取得要发送的字符串
sText += "\r\n";//添加回车换行
if(::send(m_socket, sText, sText.GetLength(), 0) != -1)
{
int nIndex = m_listData.GetItemCount();
m_listData.InsertItem(nIndex, "【发送】", 0);
m_listData.SetItemText(nIndex, 1, sText);
GetDlgItem(IDC_TEXT)->SetWindowText("");
}
}
注意:OnSock函数是消息映射函数
客户端
1 2同上
3 添加对话框
4 设置变量
5 编辑代码
// TCPClientDlg.cpp : implementation file
//
#include "stdafx.h"
#include "TCPClient.h"
#include "TCPClientDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_SOCKET WM_USER + 1 //定义网络事件通知消息
/
// 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()
/
// CTCPClientDlg dialog
CTCPClientDlg::CTCPClientDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTCPClientDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTCPClientDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTCPClientDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTCPClientDlg)
DDX_Control(pDX, IDC_DATA, m_listData);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTCPClientDlg, CDialog)
//{{AFX_MSG_MAP(CTCPClientDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CLEAR, OnClear)
ON_BN_CLICKED(IDC_CONNECT, OnConnect)
ON_BN_CLICKED(IDC_SEND, OnSend)
ON_MESSAGE(WM_SOCKET, OnSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CTCPClientDlg message handlers
BOOL CTCPClientDlg::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_bar.Create(WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP, CRect(0, 0, 0, 0), this, 101);
m_bar.SetBkColor(RGB(0xa6, 0xca, 0xf0));
int arWidth[] = { 200, -1 };
m_bar.SetParts(2, arWidth);
m_bar.SetText(" 忙碌", 1, 0);
m_bar.SetText(" 空闲", 0, 0);
m_listData.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
m_listData.InsertColumn(0, "方向", LVCFMT_LEFT, 100);
m_listData.InsertColumn(1, "数据", LVCFMT_LEFT, 170);
GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
GetDlgItem(IDC_TEXT)->EnableWindow(FALSE);
GetDlgItem(IDC_ADDR)->SetWindowText("127.0.0.1");
m_socket = INVALID_SOCKET;
return TRUE; // return TRUE unless you set the focus to a control
}
void CTCPClientDlg::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 CTCPClientDlg::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 CTCPClientDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
BOOL CTCPClientDlg::Connect(LPCTSTR pszRemoteAddr, u_short nPort)
{
m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建套接字
if( m_socket == INVALID_SOCKET)
{
return FALSE;
}
::WSAAsyncSelect(m_socket, m_hWnd,
WM_SOCKET, FD_CONNECT | FD_CLOSE | FD_WRITE | FD_READ);//设置socket为窗口通知消息类型
ULONG uAddr = ::inet_addr(pszRemoteAddr);
if( uAddr == INADDR_NONE)// 不是IP地址,就认为这是主机名称
{
hostent* pHost =::gethostbyname(pszRemoteAddr);//从主机名取得IP地址
if( pHost == NULL)
{
::closesocket(m_socket);
m_socket = INVALID_SOCKET;
return FALSE;
}
uAddr = ((struct in_addr*)*( pHost->h_addr_list))->s_addr;
}
sockaddr_in remote;
remote.sin_addr.S_un.S_addr = uAddr;
remote.sin_family = AF_INET;
remote.sin_port = htons(nPort);
::connect(m_socket, (sockaddr*)&remote, sizeof(sockaddr));//连接远程机
return TRUE;
}
void CTCPClientDlg::OnClear()
{
// TODO: Add your control notification handler code here
m_listData.DeleteAllItems();
}
void CTCPClientDlg::OnConnect()
{
// TODO: Add your control notification handler code here
if( m_socket == INVALID_SOCKET) //连接服务器
{
CString sAddr;
GetDlgItem(IDC_ADDR)->GetWindowText(sAddr);//取得服务器地址
if(sAddr.IsEmpty())
{
MessageBox("请输入服务器地址!");
return;
}
CString sPort;
GetDlgItem(IDC_PORT)->GetWindowText(sPort);//取的端口号
int nPort = atoi(sPort);
if(nPort <1 || nPort > 65535)
{
MessageBox("端口错误!");
return;
}
if( !Connect(sAddr,nPort)) //连接服务器
{
MessageBox("连接服务器出错!");
return;
}
GetDlgItem(IDC_CONNECT)->SetWindowText("取消");//设置用户界面
m_bar.SetText(" 正在连接……", 0, 0);
}
else
{
::closesocket(m_socket);//关闭套接字
m_socket = INVALID_SOCKET;
GetDlgItem(IDC_CONNECT)->SetWindowText("连接服务器");//设置用户界面
m_bar.SetText(" 空闲", 0, 0);
GetDlgItem(IDC_ADDR)->EnableWindow(TRUE);
GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
GetDlgItem(IDC_TEXT)->EnableWindow(FALSE);
GetDlgItem(IDC_SEND)->EnableWindow(FALSE);
}
}
void CTCPClientDlg::OnSend()
{
// TODO: Add your control notification handler code here
if(m_socket == INVALID_SOCKET)
{
return;
}
CString sText;
GetDlgItem(IDC_TEXT)->GetWindowText(sText);//取得要发送的字符串
sText += "\r\n";//添加回车换行
if(::send(m_socket, sText, sText.GetLength(), 0) != -1)
{
int nIndex = m_listData.GetItemCount();
m_listData.InsertItem(nIndex, "【发送】", 0);
m_listData.SetItemText(nIndex, 1, sText);
GetDlgItem(IDC_TEXT)->SetWindowText("");
}
}
long CTCPClientDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
SOCKET s= wParam;// 取得有事件发生的套节字句柄
if(WSAGETSELECTERROR(lParam))
{
if( m_socket != SOCKET_ERROR)
OnConnect();
m_bar.SetText(" 连接出错!", 0, 0);
return 0;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT: // 套节字正确的连接到服务器
{
GetDlgItem(IDC_CONNECT)->SetWindowText("断开连接");//设置用户界面
GetDlgItem(IDC_ADDR)->EnableWindow(FALSE);
GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
GetDlgItem(IDC_TEXT)->EnableWindow(TRUE);
GetDlgItem(IDC_SEND)->EnableWindow(TRUE);
m_bar.SetText(" 已经连接到服务器", 0, 0);
}
break;
case FD_READ:
{
char szText[1024];
::recv(s,szText,1024,0);
int nIndex = m_listData.GetItemCount();
m_listData.InsertItem(nIndex, "【接收】", 0);
m_listData.SetItemText(nIndex, 1, (CString(szText)));
SendData(s);
}
break;
case FD_CLOSE:
OnConnect();
break;
}
return 0;
}
void CTCPClientDlg::OnCancel()
{
// TODO: Add extra cleanup here
if(m_socket != INVALID_SOCKET)
::closesocket(m_socket);
CDialog::OnCancel();
}
void CTCPClientDlg::AddDataToList(SOCKET s, LPCTSTR pszText, BOOL bRecv)
{
sockaddr_in sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
::getpeername(s, (SOCKADDR*)&sockAddr, &nSockAddrLen); // 取得对方的IP地址和端口号
int nPeerPort = ::ntohs(sockAddr.sin_port);
CString sPeerIP = ::inet_ntoa(sockAddr.sin_addr);
DWORD dwIP = ::inet_addr(sPeerIP);
hostent* pHost = ::gethostbyaddr((LPSTR)&dwIP, 4, AF_INET);
char szHostName[256];
strncpy(szHostName, pHost->h_name, 256);
CString strItem;
if(bRecv)
{
strItem = "【接收】";
}
else
{
strItem = "【发送】";
}
strItem = strItem + CString(szHostName) + "["+ sPeerIP+ "] ";
int nIndex = m_listData.GetItemCount();
m_listData.InsertItem(nIndex, strItem, 0);
m_listData.SetItemText(nIndex, 1, pszText);
}
void CTCPClientDlg::SendData(SOCKET s)
{
char szText[1024]="数据已收到";
::send(s,szText,1024,0);
AddDataToList(s,szText,FALSE);
}