SockClient.h

#pragma once

#include<functional>

#define _WINDOWS
#ifdef _WINDOWS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#ifndef _WINSOCK2_H
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#endif
#ifndef _WINDOWS_H
#include<Windows.h>
#endif
#endif class SocketClient
{
private :
struct sockaddr_in ServerAddr;
SOCKET s;
bool stopFlag = false; public:
SocketClient();
~SocketClient();
int connectServer(char *addr,int port);
int sendToServer(char *buf, int len);
int recvFromServer(char *buf, int len);
void startRecv(std::function<void ()> recvEvent,std::function<void()> breakEvent);
};

SocketClient.cpp

#include "SocketClient.h"

SocketClient::SocketClient()
{
WORD var = MAKEWORD(, );
WSADATA wsaData;
WSAStartup(var, &wsaData); this->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
this->ServerAddr.sin_family = AF_INET; } SocketClient::~SocketClient()
{
closesocket(s);
WSACleanup();
} /*
*
* 连接到客户端
* 成功返回0 失败返回-1
*
*/
int SocketClient::connectServer(char * addr, int port)
{
this->ServerAddr.sin_port = htons(port);
this->ServerAddr.sin_addr.S_un.S_addr = inet_addr(addr); int ret = connect(s, (const sockaddr*)&this->ServerAddr, sizeof(struct sockaddr_in)); return ret;
} int SocketClient::sendToServer(char * buf, int len)
{
return send(this->s, buf, len, );
} int SocketClient::recvFromServer(char * buf, int len)
{
return recv(this->s, buf, len, );
} void SocketClient::startRecv(std::function<void()> recvEvent, std::function<void()> breakEvent)
{
this->stopFlag = true;
while (true)
{
if (stopFlag)break; fd_set readSet;
FD_ZERO(&readSet);
FD_SET(this->s, &readSet); int ret = select(this->s, &readSet, , , ); if (ret < ) {
//Connect breaks
breakEvent();
break;
}
else if (ret == ) {
//No Message
continue;
}
//Have Message
if (FD_ISSET(&readSet, this->s))
{
FD_CLR(this->s, &readSet);
recvEvent();
}
}
}

main.cpp

#include <iostream>
#include <cstring>
#include <functional> #define _WINDOWS #include "SocketClient.h" using namespace std; char IP[] = "127.0.0.1";
int Port = ;
int abc; int main()
{
SocketClient *Client = new SocketClient();
cout << "正在连接..." << endl;
if (Client->connectServer(IP, Port) != )
{
cout<< "连接失败" <<endl;
cin >> abc;
return ;
}
cout << "连接成功" << endl;
Client->startRecv([Client]() -> void {
char buf[];
int n = Client->recvFromServer(buf, );
if (n > ) {
buf[n] = '\0';
cout << "Recv: " << buf << endl;
}
}, []() -> void {
cout << "Connect break;" << endl;
});
cin >> abc;
return ;
}

select客户端模型封装——回调方式快速建立客户端的更多相关文章

  1. select服务器端模型封装——回调方式快速建立服务端

    #pragma once #ifndef WINSOCK2_H #define _WINSOCK_DEPRECATED_NO_WARNINGS #include<WinSock2.h> # ...

  2. 跨平台的游戏客户端Socket封装,调整

    原文链接:http://www.cnblogs.com/lancidie/archive/2013/04/13/3019359.html 头文件: #pragma once #ifdef WIN32 ...

  3. 如何快速建立Subversion服务器

    本文拷贝自网址:http://www.subversion.org.cn/?action-viewnews-itemid-1 如何快速建立Subversion服务器,并且在项目中使用起来,这是大家最关 ...

  4. select 函数实现 三种拓扑结构 n个客户端的异步通信 (完全图+线性链表+无环图)

    一.这里只介绍简单的三个客户端异步通信(完全图拓扑结构) //建立管道 mkfifo open顺序: cl1 读 , cl2 cl3 向 cl1写 cl2 读 , cl1 cl3 向 cl2写 cl3 ...

  5. WebService学习整理(一)——客户端三种调用方式整理

    1 WebService基础 1.1 作用 1,       WebService是两个系统的远程调用,使两个系统进行数据交互,如应用: 天气预报服务.银行ATM取款.使用邮箱账号登录各网站等. 2, ...

  6. tp5模型事件回调函数中不能使用$this

    tp5模型事件回调函数中不能使用$this,使用会报错,涉及到数据库操作使用Db类,不能使用$this->save()之类的方式 如果回调函数中需要使用类内函数,需要将函数定义为static,通 ...

  7. Swoole 协程 MySQL 客户端与异步回调 MySQL 客户端的对比

    Swoole 协程 MySql 客户端与 异步回调 MySql 客户端的对比 为什么要对比这两种不同模式的客户端? 异步 MySQL 回调客户端是虽然在 Swoole 1.8.6 版本就已经发布了, ...

  8. Oracle 数据库(oracle Database)Select 多表关联查询方式

    Oracle数据库中Select语句语法及介绍 SELECT [ ALL | DISTINCT ] <字段表达式1[,<字段表达式2[,…] FROM <表名1>,<表名 ...

  9. api接口对于客户端的身份认证方式以及安全措施

    转载 基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsession ...

随机推荐

  1. poj3191(负进位制)

    题目链接:https://vjudge.net/problem/POJ-3191 题意:将一个int范围的整数用-2进制表示并输出. 思路:将十进制转换成-2进制,原理也类似于短除法.但不同的是不是简 ...

  2. etcd集群添加节点

    查看当前集群节点信息 # etcdctl member list --write-out=table +------------------+---------+------------------- ...

  3. seata demo

    0. 介绍 2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案.Fes ...

  4. mysql生成全局id(转)

    由于数据量以及IO效率的因素,很多项目对数据支持的数据库会采取分库分表的方式.使用了分库分表之后需要解决的一个问题就是主键的生成.多个表之间的主键就不能用数据库本身的自增主键来支持,因为不同表之间生成 ...

  5. 从头到尾说一次 Java 垃圾回收,写得非常好! (转)

    之前上学的时候有这个一个梗,说在食堂里吃饭,吃完把餐盘端走清理的,是 C++ 程序员,吃完直接就走的,是 Java 程序员.

  6. php之CGI、FastCGI、php-fpm运行原理

    学好一门语言,必须懂得他得运行原理,php之CGI.FastCGI.php-fpm运行原理 早期的webserver只处理html等静态文件,但是随着技术的发展,出现了像php等动态语言.webser ...

  7. C语言中将二维数组作为函数参数来传递

    c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...

  8. 大数据计算引擎之Flink Flink状态管理和容错

    这里将介绍Flink对有状态计算的支持,其中包括状态计算和无状态计算的区别,以及在Flink中支持的不同状态类型,分别有 Keyed State 和 Operator State .另外针对状态数据的 ...

  9. css 超出部分显示省略号 汇总

    单行: 加宽度 overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 多行: display: -webkit-box; -we ...

  10. 定义一个Book类,有书名,价格,作者等信息。定义相应的方法来改变这些属性的值。定义一个方法来显示Book的所有信息。

    package com.fs.test; public class Test { public static void main(String[] args) { // 先声明后赋值 book b;/ ...