C++ Socket通信类的封装(还有点小bug)
  TEZNKK3IfmPf 2023年11月15日 49 0


  • 首先是需要引用的头文件
#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地址还没加上去 ,做测试使用


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月15日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   20天前   31   0   0 C++
  TEZNKK3IfmPf   20天前   23   0   0 指针C++
  TEZNKK3IfmPf   2024年05月31日   23   0   0 算法C++
TEZNKK3IfmPf