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