日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC:Socket编程—TCP服务端和多个客户端通信

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC:Socket编程—TCP服务端和多个客户端通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

MFC是微軟基礎類庫,于 C++ 對于 C語言來說,MFC對于window API ,MFC 就相當于C++,window API 相當于C。MFC 封裝了 window API 使用起來更加的方便。MFC中封裝的socket 直接就有事件回調,就不需要我們自己去輪詢 自己去處理,我們只需要寫好對于的事件回調函數即可,系統幫我們進行調用 方便了很多,而且 不需要多線程就可以實現 單個TCP服務器和多個TCP客戶端的通信

界面效果

MFC Socket套接字介紹

CAsyncSocket對象表示一個Windows Socket–一個網絡通信的末端。CAsyncSocket類封閉了Windows套接字API,對想使用與MFC連接的Windows套接字的程序員提供了一個面向對象的抽象化概念。
常用函數

Accept 接受套接字上的連接
Bind 與套接字有關的本地地址
Close 關閉套接字
Connect 對對等套接字建立連接
Listen 建立套接字,偵聽即將到來的連接請求
Receive 從套接字接收數據 (TCP)
ReceiveFrom 恢復數據報并且存儲資源地址 (UDP)
Send 給連接套接字發送數據 (TCP)
SendTo 給特定目的地發送數據 (UDP)

常用回調函數

OnAccept 通知偵聽套接字,它可以通過調用Accept,接受掛起連接請求
OnClose 通知套接字,關閉對它的套接字連接
OnConnect 通知連接套接字,連接嘗試已經完成,無論成功或失敗
OnReceive 通知偵聽套接字,通過調用Receive恢復數據
OnSend 通知套接字,通過調用Send,它可以發送數據

代碼

TCP服務端

CServerSocket

TCP服務端 監聽套接字類CServerSocket 重寫OnAccept函數
頭文件

#pragma once //#define _WINSOCK_DEPRECATED_NO_WARNINGS 1 #include "ConnSocket.h"#include <list> using namespace std; // CServerSocket 命令目標 class CMy02_TCPServerDlg; class CServerSocket : public CSocket { public:CServerSocket(CMy02_TCPServerDlg* dlg = NULL);virtual ~CServerSocket();// 接受到客戶端連接的 回調函數virtual void OnAccept(int nErrorCode);// 關閉所有連接套接字void CloseAllConn(); private:CMy02_TCPServerDlg* m_dlg;list<CConnSocket*> m_clientList; public: };

cpp文件

// ServerSocket.cpp : 實現文件 //#include "stdafx.h" #include "02_TCPServer.h" #include "ServerSocket.h"#include "02_TCPServerDlg.h"// CServerSocketCServerSocket::CServerSocket(CMy02_TCPServerDlg* dlg) {m_dlg = dlg; }CServerSocket::~CServerSocket() { }// CServerSocket 成員函數// 新的連接請求來了,該函數將被回調 void CServerSocket::OnAccept(int nErrorCode) {// 由框架調用,通知監聽套接字現在可以調用Accept成員函數來接收懸掛的(pending)連接請求。CConnSocket * client = new CConnSocket(m_dlg);SOCKADDR_IN addr;memset(&addr, 0, sizeof(addr));int addrLen = sizeof(addr);// 獲取通信套接字Accept(*client,(SOCKADDR*)&addr,&addrLen);char* ip = inet_ntoa(addr.sin_addr);client->SetClientAddr(CString(ip), addr.sin_port);m_clientList.push_back(client);// 界面添加連接消息CString msg;SYSTEMTIME t;GetLocalTime(&t);msg.Format(_T("[%d:%d:%d] %s:%d: connect success!"),t.wHour,t.wMinute,t.wSecond,CString(ip),addr.sin_port);m_dlg->AddMsg(msg);CSocket::OnAccept(nErrorCode); }void CServerSocket::CloseAllConn() {// 關閉監聽套接字,先關閉 連接的套接字list<CConnSocket*>::iterator it = m_clientList.begin();for (; it != m_clientList.end(); ){(*it)->Close();delete (*it);it = m_clientList.erase(it);}this->Close(); }

CConnSocket

TCP服務端 通信套接字CConnSocket
頭文件

#pragma once// CConnSocket 命令目標 class CMy02_TCPServerDlg;class CConnSocket : public CSocket { public:CConnSocket(CMy02_TCPServerDlg* dlg = NULL);virtual ~CConnSocket();virtual void OnSend(int nErrorCode);virtual void OnReceive(int nErrorCode);virtual void OnClose(int nErrorCode);// 設置連接的客戶端的IP和端口void SetClientAddr(CString ip, USHORT port); private:CString m_ip;USHORT m_port;CMy02_TCPServerDlg* m_dlg; };

對應的CPP文件

// ConnSocket.cpp : 實現文件 //#include "stdafx.h" #include "02_TCPServer.h" #include "ConnSocket.h"#include "02_TCPServerDlg.h"// CConnSocketCConnSocket::CConnSocket(CMy02_TCPServerDlg* dlg) {m_dlg = dlg; }CConnSocket::~CConnSocket() { }// CConnSocket 成員函數// 當服務器和客戶端成功建立好連接,服務器端自動調用此函數 void CConnSocket::OnSend(int nErrorCode) {// 本函數由框架調用,通知套接字現在可以調用Send成員函數發送數據了。char buf[] = "your connect success";Send(buf, strlen(buf)); //給客戶端發送信息CSocket::OnSend(nErrorCode); }// 當對方發送消息,自動調用此函數 // 可以在函數內容做接收處理 void CConnSocket::OnReceive(int nErrorCode) {// 本函數由框架調用,通知套接字緩沖中有數據,可以調用Receive成員函數取出char recvBuf[512] = { 0 };int recvLen = this->Receive(recvBuf, sizeof(recvBuf));CString msg;SYSTEMTIME t;GetLocalTime(&t);msg.Format(_T("[%d:%d:%d] %s:%d: %s"),t.wHour,t.wMinute,t.wSecond, m_ip, m_port,CString(recvBuf));m_dlg->AddMsg(msg);// 回射信息CharUpperA(recvBuf);this->Send(recvBuf, strlen(recvBuf)); }// 對方主動斷開連接,自動調用此函數 void CConnSocket::OnClose(int nErrorCode) {CString msg;SYSTEMTIME t;GetLocalTime(&t);msg.Format(_T("[%d:%d:%d] %s:%d: already close!"), t.wHour,t.wMinute,t.wSecond,m_ip, m_port);m_dlg->AddMsg(msg);CSocket::OnClose(nErrorCode); }void CConnSocket::SetClientAddr(CString ip, USHORT port) {m_ip = ip;m_port = port; }

TCP客戶端

CConnSocket

TCP客戶端 通信套接字
頭文件

#pragma onceclass CMy02_TCPClientDlg; // CConnSocket 命令目標class CConnSocket : public CSocket { public:CConnSocket(CMy02_TCPClientDlg* dlg = NULL);virtual ~CConnSocket();BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);virtual void OnConnect(int nErrorCode);virtual void OnClose(int nErrorCode); private:CMy02_TCPClientDlg* m_dlg;CString m_ip;UINT m_port; public:virtual void OnReceive(int nErrorCode); };

cpp文件

// ConnSocket.cpp : 實現文件 //#include "stdafx.h" #include "02_TCPClient.h" #include "ConnSocket.h" #include "02_TCPClientDlg.h"// CConnSocketCConnSocket::CConnSocket(CMy02_TCPClientDlg* dlg) {m_dlg = dlg; }CConnSocket::~CConnSocket() { }BOOL CConnSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort) {m_ip = lpszHostAddress;m_port = nHostPort;return CAsyncSocket::Connect(lpszHostAddress, nHostPort); }// CConnSocket 成員函數// 連接服務器成功,該函數會被調用 void CConnSocket::OnConnect(int nErrorCode) {// 本函數由框架調用,通知該套接字連接操作已經完成,并且說明連接是成功還是失敗了。CSocket::OnConnect(nErrorCode); }void CConnSocket::OnClose(int nErrorCode) {// 由框架調用通知該套接字,它連接上的對應套接字已經被相關進程終止了CString msg;SYSTEMTIME t;GetLocalTime(&t);msg.Format(_T("[%d:%d:%d] %s:%d: already close!"), t.wHour, t.wMinute, t.wSecond, m_ip, m_port);m_dlg->AddMsg(msg);m_dlg->MyEnableBtn();this->Close();CSocket::OnClose(nErrorCode); }void CConnSocket::OnReceive(int nErrorCode) {// 本函數由框架調用,通知套接字緩沖中有數據,可以調用Receive成員函數取出char recvBuf[512] = { 0 };int recvLen = this->Receive(recvBuf, sizeof(recvBuf));CString msg;SYSTEMTIME t;GetLocalTime(&t);msg.Format(_T("[%d:%d:%d] %s:%d: %s"), t.wHour,t.wMinute, t.wSecond, m_ip, m_port, CString(recvBuf));m_dlg->AddMsg(msg);CSocket::OnReceive(nErrorCode); }

完整代碼

如果有需要 這里下載完整工程

總結

以上是生活随笔為你收集整理的MFC:Socket编程—TCP服务端和多个客户端通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。