0. 封装原因
主要因为Windows socket 相关的API调用步骤比较繁琐。
1. 头文件
#pragma once #include <WinSock2.h> #pragma comment(lib, "Ws2_32.lib") class CSocketLzf { protected: SOCKET m_hSocket; public: BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort); BOOL Accept(CSocketLzf & rConnectedSocket, LPSTR szIP = NULL, UINT * nPort = NULL); BOOL GetPeerName(LPTSTR rSocketAddress, UINT &rSocketPort); BOOL GetSockName(LPTSTR rSocketAddress, UINT &rSocketPort); BOOL Create(UINT nSocketPort = 0U, int nSocketType = SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL); int SendTo(const void * lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszSocketAddress = NULL, int nFlag = 0); int RecvFrom(void * lpBuf, int nBufLen, char * rSocketAddress, UINT & rSocketPort, int nFlag = 0); int Recv(void *lpBuf, int nBufLen, int nFlag = 0) { return recv(m_hSocket, (LPTSTR)lpBuf, nBufLen, nFlag); } int Send(const void *lpBuf, int nBufLen, int nFlag = 0) { return send(m_hSocket, (LPTSTR)lpBuf, nBufLen, nFlag); } void Close() { closesocket(m_hSocket); m_hSocket = INVALID_SOCKET; } BOOL Listen(int backlog = 5) { return listen(m_hSocket, backlog); } CSocketLzf(); virtual ~CSocketLzf(); };
2. 源文件
#define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include "SocketLzf.h" BOOL CSocketLzf::GetPeerName(LPTSTR rSocketAddress, UINT & rSocketPort) { struct sockaddr_in sa = {AF_INET}; int nLen = sizeof(sa); if (SOCKET_ERROR == getpeername(m_hSocket, (struct sockaddr *)&sa, &nLen)) return FALSE; strcpy(rSocketAddress, inet_ntoa(sa.sin_addr)); rSocketPort = htons(sa.sin_port); return TRUE; } BOOL CSocketLzf::GetSockName(LPTSTR rSocketAddress, UINT & rSocketPort) { struct sockaddr_in sa = { AF_INET }; int nLen = sizeof(sa); if (SOCKET_ERROR == getsockname(m_hSocket, (struct sockaddr *)&sa, &nLen)) return FALSE; strcpy(rSocketAddress, inet_ntoa(sa.sin_addr)); rSocketPort = htons(sa.sin_port); return TRUE; return 0; } BOOL CSocketLzf::Create(UINT nSocketPort, int nSocketType, LPCTSTR lpszSocketAddress) { m_hSocket = socket(AF_INET, nSocketType, 0); if (m_hSocket == INVALID_SOCKET) return FALSE; struct sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_port = htons(nSocketPort); if (lpszSocketAddress != NULL) sa.sin_addr.s_addr = inet_addr(lpszSocketAddress); else sa.sin_addr.s_addr = NULL; return !bind(m_hSocket, (struct sockaddr *)&sa, sizeof(sa)); } int CSocketLzf::SendTo(const void * lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszSocketAddress, int nFlag) { struct sockaddr_in sa; sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(lpszSocketAddress); sa.sin_port = htons(nHostPort); return sendto(m_hSocket, (LPCTSTR)lpBuf, nBufLen, nFlag, (struct sockaddr *)&sa, sizeof(sa)); } int CSocketLzf::RecvFrom(void * lpBuf, int nBufLen, char * rSocketAddress, UINT & rSocketPort, int nFlag) { struct sockaddr_in sa = { AF_INET }; int nLen = sizeof(sa); recvfrom(m_hSocket, (LPTSTR)lpBuf, nBufLen, nFlag, (struct sockaddr *)&sa, &nLen); strcpy(rSocketAddress, inet_ntoa(sa.sin_addr)); rSocketPort = htons(sa.sin_port); return nLen; } BOOL CSocketLzf::Connect(LPCTSTR lpszHostAddress, UINT nHostPort) { struct sockaddr_in sa = {AF_INET}; sa.sin_addr.s_addr = inet_addr(lpszHostAddress); sa.sin_port = htons(nHostPort); return !connect(m_hSocket, (struct sockaddr*)&sa, sizeof(sa)); } BOOL CSocketLzf::Accept(CSocketLzf & rConnectedSocket, LPSTR szIP, UINT * nPort) { struct sockaddr_in sa = { AF_INET }; int nLen = sizeof(sa); SOCKET socka = accept(m_hSocket, (struct sockaddr*)&sa, &nLen); if (socka == INVALID_SOCKET) return FALSE; rConnectedSocket.m_hSocket = socka; strcpy(szIP, inet_ntoa(sa.sin_addr)); *nPort = htons(sa.sin_port); return TRUE; } CSocketLzf::CSocketLzf() { struct WSAData wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata); m_hSocket = INVALID_SOCKET; } CSocketLzf::~CSocketLzf() { Close(); }
3. 调用示例
#include "SocketLzf.h" #include <iostream> using namespace std; int main() { CSocketLzf sock; BOOL n = sock.Create(8887); if (!n) { cout << "错误代码:" << GetLastError() << endl; return -1; } sock.Listen(); char buf[2048] = { 0 }; char strIP[20] = { 0 }; UINT nPort = 0; while (true) { CSocketLzf sock_cln; if (sock.Accept(sock_cln, strIP, &nPort)) { cout << "客户端:" << strIP << ":" << nPort << "已登录!" << endl; while (true) { int n = sock_cln.Recv(buf, sizeof(buf)); if (n <= 0) break; cout << "收到来自" << strIP << ":" << nPort << "的消息:" << buf << endl; memset(buf, ' ', sizeof(buf)); } sock_cln.Close(); cout << "客户端:" << strIP << ":" << nPort << "已断开连接!" << endl; } } sock.Close(); return 0; }