TCP网络通信
2012-10-31 14:17
155 查看
服务器:
1 在StdAfx.h中引入<winsock2.h>
2 初始化Winsock库
WSADATA wsaData; (WSDATA/article/9661843.html)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); }
相关文章推荐
- 基于TCP的网络通信(SCOKET)
- 【转】win32平台TCP网络通信模块客户端
- 超基础的网络编程02:基于TCP的Socket通信
- java 基于TCP的Socket网络通信
- 基于TCP的协议封装及Netty搭建高可用网络通信服务
- 图解TCP UDP建立网络通信的模型,
- 基于TCP网络通信的自动升级程序源码分析-服务器发送文件
- boost::asio::ip::tcp实现网络通信的小例子
- tcp 网络通信基本原理
- 【开源下载】基于TCP网络通信的自动升级程序c#源码
- 基于TCP网络通信的自动升级程序源码分析--生成升级文件相关的配置文件
- Linux之—网络通信(TCP)
- TCP网络通信的简单例子
- 通信网络实验——TCP 的socket实现
- VC++实现检测网络状态所有的TCP与UDP通信
- Java-网络通信、TCP、UDP、服务器客户端的通信
- Linux网络通信(二)Socket编写TCP/UDP
- [python] 专题七.网络编程之套接字Socket、TCP和UDP通信实例
- 网络通信之TCP
- linux 网络编程之最简单的tcp通信客户端