MFC下CSocket编程详解.pdf
### MFC 下 CSocket 编程详解 #### 一、CSocket 类介绍及常用函数 在 MFC(Microsoft Foundation Classes)环境下,`CSocket` 类是用于实现网络通信的一个核心类,它基于 Windows Socket API(Winsock API)封装了一系列网络编程功能。下面将详细介绍 `CSocket` 的一些常用函数及其使用注意事项。 ##### 1.1 CSocket::Create - **函数原型**: ```cpp virtual int Create( UINT nProtocol = PF_INET, UINT nType = SOCK_STREAM, UINT nProtocolInstance = IPPROTO_TCP ); ``` - **描述**: - 初始化一个 `CSocket` 对象,用于创建一个新的套接字。 - 通常情况下,在编写服务器程序时建议避免使用此函数,因为可能会遇到端口冲突问题(例如错误号 10048)。 - 推荐使用 `CSocket::Socket` 方法替代。 ##### 1.2 CSocket::Socket - **函数原型**: ```cpp virtual SOCKET Socket( UINT nProtocol = PF_INET, UINT nType = SOCK_STREAM, UINT nProtocolInstance = IPPROTO_TCP ); ``` - **描述**: - 与 `CSocket::Create` 类似,但更加灵活且不易出现端口冲突的问题。 - 创建一个新的套接字,并返回一个 SOCKET 类型的句柄。 ##### 1.3 CSocket::SetSockOpt - **函数原型**: ```cpp virtual int SetSockOpt( int nLevel, int nOptionName, const char* lpOptionValue, int nOptionLen ); ``` - **描述**: - 设置套接字选项,如 TCP_NODELAY 等。 - `nLevel` 表示设置选项的级别,如 SOL_SOCKET 或 IPPROTO_TCP。 - `nOptionName` 指定具体的选项名称,如 SO_REUSEADDR 或 TCP_NODELAY。 - `lpOptionValue` 是指向值的指针,而 `nOptionLen` 表示值的长度。 ##### 1.4 CSocket::Bind - **函数原型**: ```cpp virtual int Bind( const sockaddr* pAddr, int nAddrLen ); ``` - **描述**: - 绑定本地地址和端口号到套接字上。 - 通常在服务器端使用,将服务绑定到特定的端口上。 ##### 1.5 CSocket::Connect - **函数原型**: ```cpp virtual int Connect( const sockaddr* pAddr, int nAddrLen ); ``` - **描述**: - 连接到远程服务器的指定地址和端口。 - 客户端程序使用该函数建立连接。 ##### 1.6 CSocket::Listen - **函数原型**: ```cpp virtual int Listen( int nBackLog = 5 ); ``` - **描述**: - 使服务器进入监听状态,准备接受客户端的连接请求。 - 参数 `nBackLog` 指定了连接队列的长度,默认为 5。 ##### 1.7 CSocket::Accept - **函数原型**: ```cpp virtual SOCKET Accept( sockaddr* pAddr = NULL, int* pnAddrLen = NULL ); ``` - **描述**: - 接受一个传入的连接请求,并创建一个新的套接字来处理该连接。 - 可以获取客户端的地址信息。 ##### 1.8 CSocket::Send - **函数原型**: ```cpp virtual int Send( LPCVOID lpBuf, int nBufLen, int nFlags = 0 ); ``` - **描述**: - 发送数据到已连接的套接字。 - `lpBuf` 是指向要发送的数据的指针,`nBufLen` 是数据的长度。 ##### 1.9 CSocket::Receive - **函数原型**: ```cpp virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 ); ``` - **描述**: - 从已连接的套接字接收数据。 - `lpBuf` 是用于接收数据的缓冲区指针,`nBufLen` 是缓冲区的大小。 - 注意,这是一个阻塞函数,直到有数据到达或发生错误才会返回。 ##### 1.10 CSocket::Close - **函数原型**: ```cpp virtual void Close(); ``` - **描述**: - 关闭当前的套接字连接。 - 注意,这不等于删除对象,仅仅是关闭套接字。 #### 二、使用注意事项 1. **包含头文件**: - 在使用 `CSocket` 类之前,必须包含 `<afxsock.h>` 文件。 2. **初始化 Winsock**: - 必须调用 `AfxSocketInit()` 函数来初始化 Winsock 库。 - 即便主程序已经调用了 `AfxSocketInit()`,在每个使用 `CSocket` 的线程中也需要重新调用。 3. **Create 和 Bind 方法**: - 如果使用了 `Create` 方法,则不应该再调用 `Bind` 方法,因为 `Create` 方法内部已经包含了 `Bind` 功能。 - 若想绑定特定端口,请直接使用 `Socket` 方法创建套接字,然后调用 `Bind` 方法。 #### 三、示例代码解析 以下分别提供了一个简单的客户端和服务端的示例代码,用于演示如何使用 `CSocket` 类进行网络编程。 ##### 3.1 客户端示例 ```cpp // 客户端初始化 AfxSocketInit(); // 创建 CSocket 对象 CSocket aSocket; CString strIP; CString strPort; CString strText; this->GetDlgItem(IDC_EDIT_IP)->GetWindowText(strIP); this->GetDlgItem(IDC_EDIT_PORT)->GetWindowText(strPort); this->GetDlgItem(IDC_EDIT_TEXT)->GetWindowText(strText); // 初始化 CSocket 对象 if (!aSocket.Create()) { char szMsg[1024] = {0}; sprintf(szMsg, "create failed: %d", aSocket.GetLastError()); AfxMessageBox(szMsg); return; } // 转换需要连接的端口内容类型 int nPort = atoi(strPort); // 连接到指定的地址和端口 if (aSocket.Connect(strIP, nPort)) { char szRecValue[1024] = {0}; // 发送内容给服务器 aSocket.Send(strText, strText.GetLength()); // 接收服务器发送回来的内容 aSocket.Receive((void*)szRecValue, 1024); AfxMessageBox(szRecValue); } else { char szMsg[1024] = {0}; sprintf(szMsg, "connect failed: %d", aSocket.GetLastError()); AfxMessageBox(szMsg); } // 关闭连接 aSocket.Close(); ``` ##### 3.2 服务器端示例 ```cpp unsigned int StartServer(LPVOID lParam) { // 初始化 Winsock if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return 1; } m_exit = false; CServerDlg* aDlg = (CServerDlg*)lParam; CString strPort; aDlg->GetDlgItemText(IDC_EDIT_PORT, strPort); UINT nPort = atoi(strPort); // socket ------------------------------------------------ CSocket aSocket, serverSocket; // 最好不要使用 aSocket.Create 创建,因为容易会出现 10048 错误 if (!aSocket.Socket()) { char szError[256] = {0}; sprintf(szError, "socket creation failed: %d", aSocket.GetLastError()); AfxMessageBox(szError); return 1; } // ...后续代码 } ``` 以上示例展示了如何使用 `CSocket` 类实现客户端和服务端的基本通信过程。需要注意的是,这些示例代码仅为基本框架,实际应用中可能还需要考虑异常处理、线程安全等问题。
剩余9页未读,继续阅读
- JYunGe2012-06-13之前看过,把网页资源转成pdf,以CSocket为关键词搜索,很容易找到该网页
- jj606620022012-06-23適合初學者, 完全沒接觸过CWINSOECK的人,
- 粉丝: 312
- 资源: 2157
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助