欢迎来到我的博客https://www.cnblogs.com/veis/

https://www.cnblogs.com/veis/p/14182037.html

分享一个自己封装的WIN SOCKET类

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, '\0', sizeof(buf));
			}
			sock_cln.Close();
			cout << "客户端:" << strIP << ":" << nPort << "已断开连接!" << endl;
		}
	}
	sock.Close();

	return 0;
}

  

posted @ 2020-05-04 08:23  veis  阅读(373)  评论(0编辑  收藏  举报