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

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

  1. java Socket通信(一)

    ava socket通信已经被封装好了主要使用两个类ServerSocket 和Socket 首先写一个1v1的通信 服务端 /** * */ package com.dnion.socket; im ...

  2. python socket通信 PC和树莓派

    目录 前言 什么是socket通信 socket的python实现 PC端 PC端通信模块 PC端实现demo 树莓派端 树莓派端通信模块 树莓派和PC之间的文件传输--FileZilla 前言 什么 ...

  3. socket 通信 封装 协议 基础

    Big Endian && Little Endian endian 字节存储次序 端模式 Big Endian 是低端地址存放最高有效字节(MSB) Little Endian 低端 ...

  4. Flash与jsp通信类封装

    今天写了一个通信类,可以实现和JSp进行数据交互.粘贴在一起,有兴趣可以尝试一下 package { //用于与网页通信的东西 import flash.net.URLLoader; import f ...

  5. C++管道通信类封装

    简单的介绍一下,管道通信类 指的是 IPC通信中的一种,即两个不同的进程之间的通信 现在实现一下管道通信类,方便以后调用使用 头文件(引用相关的库) // stdafx.h : 标准系统包含文件的包含 ...

  6. linux socket通信出错封装处理

    linux socket通信出错封装处理 wrap.c #include <stdlib.h> #include <errno.h> #include <sys/sock ...

  7. 通信类专业也可以考国家电网!而且待遇还不错~

    国家电网是全球最大的公用事业企业,公司经营区域覆盖26个省(自治区.直辖市),覆盖国土面积的88%以上,供电服务人口超过11亿人. 公司注册资本8295亿元,资产总额3.93万亿元,稳健运营在菲律宾. ...

  8. Socket通信之TCP拆包和封包

    前言 我们在使用Socket传递信息时候,经常会遇到这样的问题,输入流数据读取不完整,或者输入流读取数据错乱的问题.下面就针对这俩个问题谈谈我的想法,以及解决思路. 举例说明 最近我在做一个工业物联网 ...

  9. socket通信之六:Overlapped I/O 事件通知模型实现的客户/服务器模型

    1.基于事件通知模型的Overlapped I/O(重叠IO模型) 概括一点说,重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求.针对这 ...

最新文章

  1. 如何理解物体的6D位姿估计任务?
  2. json.parse()和json.stringify()
  3. MIT与TI研究人员已打造出新型防黑RFID芯片
  4. 个人linux版本管理,浅谈各个Linux版本的个人看法
  5. CLion导入用户自己的lib和头文件
  6. ARM 汇编基础教程番外篇 ——配置实验环境
  7. mysql in 子查询优化_mysql in 子查询 容易优化
  8. 客户端级别的渲染分析工具 dynaTrace
  9. usb 系统消息_别让 USB 传输速度影响 Android 开发效率
  10. 腾讯开源业界首个云原生标准的一站式微服务管理框架Femas
  11. 简单的解决达梦数据库查询 dm.jdbc.driver.DmdbNClob@1064bb3e 问题
  12. 【转】框架(蔡学镛)
  13. 大话西游2人数最多服务器,大话2大话各个服务器狂人榜排名 看大话如今服务器...
  14. 让ADB识别未知设备...
  15. 通过同花顺股票程序化交易接口的止损方法有哪些?
  16. 薪酬管理系统功能描述文档
  17. k8s的Scheduler 原理(预选策略、优选策略)
  18. Codeup-2044:神奇的口袋
  19. 李建忠设计模式之“单一职责”模式
  20. HTML制作简单课表

热门文章

  1. 多线程中的事务回滚,你真的用对了吗?
  2. 部份API学习笔记(Math,System,Object,Date,SimpleDateFormat)
  3. Oracle主要概念汇总
  4. 服务状态已停止_虾米音乐今日宣布关停,新平台”音螺“相关商标已注册
  5. Springboot2拦截器与文件上传
  6. SpringMVC框架----SessionAttribute注解
  7. Linux 打包和压缩
  8. NetworkManager概述
  9. 用bat批处理程序通过DOS命令行删除所有的空文件夹
  10. CSS 强制换行和禁止换行学习