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;
}