C++ Socket通信类的封装(还有点小bug)

  • 首先是需要引用的头文件
#define WIN32_LEAN_AND_MEAN // 排除极少使用的链接
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
// TODO: 在此处引用程序需要的其他头文件
  • 第二个是YTSocket类的声明
#include "stdafx.h"

enum SOCKET_{
	SOCKET_CLIENT = 1, //客户端
	SOCKET_SERVER, //服务端
};


class YTSocket{
public:
	YTSocket();
	~YTSocket();
	static YTSocket* GetInstance(); //获取实例

	bool InitSocket(SOCKET_ type_,int socket_ip,int socket_port);//初始化ip 端口号
	bool ListenData(); //接收数据
	bool SendMsgToClient(std::string& datas); //发送消息给客户端
	bool SendMsgToServer(std::string& datas);//发送消息给服务器;
	bool StopAll();//提前终止
	bool ListenAllData();//即可以通过多线程的方式监听数据,主线程可以继续发消息 不影响

private:
	static YTSocket* m_yts;
	SOCKET  m_socket;
	SOCKET  m_rec_socket; //接听消息的socket;
	SOCKET_ m_socket_type; //Socket类型:客户端or服务端
	int    m_listen_state;//接收状态 1为接收 0为未接收
};
  • 此处为实现类
// YTSocket.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "YTSocket.h"

using namespace std;
//公共变量
SOCKET g_m_recsocket = INVALID_SOCKET;

YTSocket* YTSocket::m_yts = NULL; //初始化为空

struct ListenStruct{
	SOCKET socket_t;
	int  socket_state;
};

DWORD WINAPI ListenPort(LPVOID lpParams){
	
	cout << "启动异步监听" << endl;
	//创建监听消息
	ListenStruct * m_struct = (ListenStruct*)lpParams;
	SOCKET m_socket = m_struct->socket_t;
    int type_ =	m_struct->socket_state;
	if (type_ == 1)
	{
		//为监听客户端的处理
		//1.开启监听
		if (listen(m_socket,5)== SOCKET_ERROR) 
		{
			cout << "socket 监听失败" << endl;
			return false;
		}
		//2.启动接收数据
		sockaddr_in remoteAddr;
		int len_RemoteAddr = sizeof(remoteAddr);
		char recData[255] = {0};
		SOCKET m_rec_socket = INVALID_SOCKET;
		//3.进行接听消息
		while(true)
		{
			m_rec_socket = accept(m_socket,(SOCKADDR*)&remoteAddr,&len_RemoteAddr);
			if (m_rec_socket == INVALID_SOCKET)
			{
				cout << "接收消息无效" << endl;
				//重新接听;
				continue;
			}
			g_m_recsocket = m_rec_socket;
			cout << "接收到一条连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;
			int ret = recv(m_rec_socket,recData,1024,0); //默认接收1024;
			if (ret > 0)
			{
				cout <<"客户端传来的消息为:" <<recData << endl;
			}
		}
	}
	else
	{
		//为监听服务端的处理
		//处理客户端接收数据问题
		while(true)
		{
			char recData[1024]={0};
			//客户端接收消息
			int ret = recv(m_socket,recData,1024,0); //默认接收1024;
			if (ret > 0)
			{
				cout <<"服务端传来的消息为:" <<recData << endl;
			}
		}
	}
}

//获取静态实例 单例模式
YTSocket* YTSocket::GetInstance()
{
	if (m_yts == nullptr)
	{
		m_yts = new YTSocket();
		return m_yts;
	}
	return m_yts;
}


YTSocket::YTSocket()
{
	m_socket = INVALID_SOCKET;//初始化 
	m_rec_socket = INVALID_SOCKET;//初始化
	m_listen_state = 0;
	//进行初始化
	WSADATA wsa_data;
	WORD version_ = MAKEWORD(2,2); //设置SOCKET版本号
	int err = WSAStartup(version_,&wsa_data);
	if (err == 0)
	{
		cout << "初始化套接字成功!" << endl;//	
	}

}

YTSocket::~YTSocket(){
	cout << "YTSocket被析构了" << endl;
	if (m_rec_socket!= INVALID_SOCKET)
	{
		closesocket(m_rec_socket);
	}
	if (m_socket!=INVALID_SOCKET)
	{
		closesocket(m_socket);
	}
    WSACleanup();
}

//初始化Socket
bool YTSocket::InitSocket(SOCKET_ type_,int socket_ip,int socket_port)
{
	if (type_ == SOCKET_CLIENT)
	{
		m_socket_type = type_;
	}
	else if (type_ = SOCKET_SERVER)
	{
		m_socket_type = type_;
	}
	else
	{
		cout << "Socket Type 指定错误" << endl;
		return false;
	}

	if (m_socket_type == SOCKET_SERVER)
	{
		//服务端
		//1.初始化SOCKET
		m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //设定类型
		if (m_socket == INVALID_SOCKET)
		{
			cout << "socket 初始化失败" << endl;
			return false;
		}
		//2.绑定ip和端口号
		sockaddr_in sin;
		sin.sin_family = AF_INET;
		sin.sin_port = htons(socket_port); //绑定端口号
		sin.sin_addr.S_un.S_addr = INADDR_ANY; //绑定ip地址:所有
		if (bind(m_socket,(LPSOCKADDR)&sin,sizeof(sin)) == SOCKET_ERROR)
		{
			cout << "socket 绑定端口号失败!" << endl;
			return false;
		}
		return true;
	}
	else{
		//客户端
		m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if(m_socket == INVALID_SOCKET)
		{
			cout << "socket invalid" << endl;
			return false;
		}
		sockaddr_in serAddr;
		serAddr.sin_family = AF_INET;
		serAddr.sin_port = htons(socket_port);
		serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
		if(connect(m_socket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
		{  
			cout << "连接失败" << endl;
			closesocket(m_socket);
			return false;
		}
		return true;
	}
	return true;
}

//接收数据
bool YTSocket::ListenData()
{
	if (m_listen_state == 1)
	{
		cout << "已经在监听数据,无需重复开启" << endl;
		return true;
	}
	else
	{
		m_listen_state =1;
	}
	//如果是服务器接收数据的话
	if (m_socket_type == SOCKET_SERVER)
	{
		//1.开启监听
		if (listen(m_socket,5)== SOCKET_ERROR) 
		{
			cout << "socket 监听失败" << endl;
			return false;
		}
		//2.启动接收数据
		sockaddr_in remoteAddr;
		int len_RemoteAddr = sizeof(remoteAddr);
		char recData[255] = {0};
		//3.进行接听消息
		while(true)
		{
			m_rec_socket = accept(m_socket,(SOCKADDR*)&remoteAddr,&len_RemoteAddr);
			if (m_rec_socket == INVALID_SOCKET)
			{
				cout << "接收消息无效" << endl;
				//重新接听;
				continue;
			}
			cout << "接收到一条连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;
			int ret = recv(m_rec_socket,recData,1024,0); //默认接收1024;
			if (ret > 0)
			{
				cout <<"客户端传来的消息为:" <<recData << endl;
			}
		}
	}
	else
	{
		//处理客户端接收数据问题
		while(true)
		{
			char recData[1024]={0};
			//客户端接收消息
			int ret = recv(m_socket,recData,1024,0); //默认接收1024;
			if (ret > 0)
			{
				cout <<"服务端传来的消息为:" <<recData << endl;
			}
		}
	}
	return true;
}

bool YTSocket::ListenAllData()
{
	if (m_listen_state == 1)
	{
		cout << "已经在监听数据,无需重复开启" << endl;
		return true;
	}
	else
	{
		m_listen_state =1;
	}
	if (m_socket_type == SOCKET_SERVER)
	{
		ListenStruct stc;
		stc.socket_state = 1;
		stc.socket_t = m_socket;
		CreateThread(NULL, 0, &ListenPort, &stc, 0, NULL);
		return true;
	}
	else
	{
		ListenStruct stc;
		stc.socket_state = 0;
		stc.socket_t = m_socket;
		CreateThread(NULL, 0, &ListenPort, &stc, 0, NULL);
		return true;
	}

}

bool YTSocket::SendMsgToServer(std::string& datas)
{
	if (m_socket == INVALID_SOCKET)
	{
		cout << "socket 连接失败" << endl;
		return false;
	}
	send(m_socket,datas.c_str(),strlen(datas.c_str()),0);
	return true;
}

bool YTSocket::SendMsgToClient(std::string& datas)
{
	if(m_rec_socket == INVALID_SOCKET)
	{
		cout << "客户端无效" << endl;
		return false;
	}
	send(m_rec_socket,datas.c_str(),strlen(datas.c_str()),0);
	cout << "服务端发送成功" << endl;
	return true;
}

bool YTSocket::StopAll()
{
	if (m_rec_socket!= INVALID_SOCKET)
	{
		closesocket(m_rec_socket);
	}
	if (m_socket!=INVALID_SOCKET)
	{
		closesocket(m_socket);
	}
	WSACleanup();
	return true;
}


  • 如何使用该类
  • 服务端的使用
int _tmain(int argc, _TCHAR* argv[])
{
	//测试服务端
	YTSocket::GetInstance()->InitSocket(SOCKET_SERVER,1000,8008);//绑定端口号
	YTSocket::GetInstance()->ListenData();
	//主线程如何保证不听再跑
	std::string dtas  = "测试数据一下";
	YTSocket::GetInstance()->SendMsgToClient(dtas);
	system("pause");
	return 0;
}
  • 客户端的使用
	YTSocket::GetInstance()->InitSocket(SOCKET_CLIENT,1000,8008);
	string datas = "服务端,你收到了吗?";
	YTSocket::GetInstance()->SendMsgToServer(datas);
	YTSocket::GetInstance()->SendMsgToServer(datas);
	YTSocket::GetInstance()->ListenData();
	//string datas_r = "服务端, 你还能收到吗?";
	//YTSocket::GetInstance()->SendMsgToServer(datas_r);
	system("pause");
	return 0;
  • 运行结果:
    在这里插入图片描述
  • 还有点小bug:
  • 1.socket异步处理还有点问题
  • 2.ip地址还没加上去 ,做测试使用
发布了365 篇原创文章 · 获赞 80 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/Giser_D/article/details/103990310