Socket网络编程
Evillla
努力做一个可爱的程序员
展开
-
C++ Socket网络编程 简易服务端1.0版本搭建(一)
学习目标:1、掌握多平台C++程序的设计、编码、调试和发布2、掌握Select、IOCP、epoll 网络通信模型3、掌握主流平台下使用C++ 进行TCP网络通信4、掌握游戏引擎中使用C++ TCP通信5、掌握后端开发性能优化技巧6、掌握多线程、内存管理(内存池、对象池)的实现和运用第一讲:运用C++和Socket API构建百万级处理能力网络通信引擎首先感谢伟大的刘远东老师!!!...原创 2019-04-04 20:28:05 · 1851 阅读 · 1 评论 -
C++ Socket网络编程 解决网络阻塞和粘包\少包的问题(服务端)
服务端与客户端最大的不同是,服务端会接收多个客户端发送的网络数据,因此对服务端的改进是相对复杂的。未完待续…原创 2019-04-09 18:34:14 · 659 阅读 · 0 评论 -
C++ Socket网络编程1.6版本 突破Winows系统中的连接限制
在Linux系统中,select网络模型中的fd_set具有1024个连接数处理能力,windows系统中只有64个。那么在Windows中使用select网络模型,支持超过64个socket连接呢?在WinSock2.h的文件中,对fd_set处理数量进行了如下宏定义。因此,在引入WinSock2.h文件之前,对这个宏进行定义,以达到超过64个连接的限制。#ifndef FD_SETSI...原创 2019-04-13 16:25:33 · 407 阅读 · 1 评论 -
C++ Socket网络编程1.6版本 添加高精度计时器测量处理能力
目前的版本中,通过修改Windows下FD_SETSIZE这个宏定义,来打破select只能处理64个socket收发限制。因此,开通了1000个客户端去连接服务端以测试性能。通过在资源管理器中可以查看,每秒达到150M左右的收发网络数据能力(这个数值与计算机硬件设备和操作系统的限制相关)。C++ 11中引入了精准的跨平台的计时器,简单的实现如下:这个是一个C++11新引入的计时器,通过cp...原创 2019-04-14 16:44:36 · 386 阅读 · 0 评论 -
C++ 多线程、锁、临界区、自解锁与原子操作
C++ 11 引入了线程库, #include <thread>一般简单的,编写一个线程执行的函数,传递给thread去开启线程,就可以简单的实现多线程程序。void WorkFun(int param){ ... for(int i = 0;i<4;i++) { cout<<param<<"Hello, other thread." &l...原创 2019-04-14 17:32:51 · 1388 阅读 · 0 评论 -
C++Socket 多线程编程 客户端1.7版本 多线程分组模拟高频发送数据
1、客户端1.7版本 多线程分组模拟高频发送数据如上图所示的多线程客户端结构,启动多个线程对客户端进行socket创建->连接->发送的业务;//客户端socket连接数量const int cCount = 1000;const int tCount = 4; //线程数量//客户端socket数组EasyTcpClient* client[cCount];mutex ...原创 2019-04-15 11:14:18 · 644 阅读 · 0 评论 -
C++Socket 多线程编程 定时和定量发送数据
C++ Socket API中 发送函数Send和接收函数Recv函数的调用不一定是1对1的关系。对于服务器来说,它收到了一个网络消息调用了一次Recv,并且需要回复给客户端并调用send函数,那么其实大多数情况下,send的调用次数会大于recv的调用次数。因为服务器收到了一个网络消息之后,可能要通知多个客户端,服务器要做的响应。考虑这样一个情景:构建一个 万人同服的网络游戏,需要对每个人做的...原创 2019-06-07 10:26:22 · 2513 阅读 · 1 评论 -
C++Socket 多线程编程 服务端收发数据业务分离
当前存在的问题在目前版本的网络通信引擎中,服务端收到数据(recv)后,会立即对给它发网络数据的客户端返回一个网络数据包(send),并且recv和send的做法是在同一个线程中的。那么存在什么问题呢? 我们都知道TCP是面向字节流的传输协议,TCP连接的双方都有一个数据缓冲区用来接收数据。那么如果一方发送的速度远大于另一方接收的速度时,可能会导致接收方的缓冲区满,从而导致网络阻塞。在同一个...原创 2019-06-07 20:11:29 · 2621 阅读 · 0 评论 -
C++ 内存管理-对象池的设计与实现
前言对象池与内存池的设计思路大体相同,如果我们的程序需要对一个类的对象进行大规模的申请和释放,用内存池也没有问题。但是由于内存池的内存块大小可能会与对象的大小不一致,从而导致内存块的碎片相对较多,因此通过构建一个对象池,对某个类的对象的内存申请和释放进行管理。那么考虑一下对象池和内存池的区别?1、对象池管理的是某个类的对象的内存管理,内存池管理的是内存块。2、内存池重载了全局的new/de...原创 2019-06-13 21:01:10 · 969 阅读 · 1 评论 -
C++Socket 多线程编程 select/网络IO的性能瓶颈级优化
select I/O复用模型的工作机制是将想要检测的socket通过FD_SET宏将描述符放入到fd_set集合中,然后将fd_set这个描述符集合传入到select函数中进行检测。因此,每次在调用select函数之前,需要将想要检测的socket都放入fd_set中。那么当服务器检测的socket集合没有发生变化的时候,每次调用select函数都执行FD_SET宏将描述符放入到fd_set集...原创 2019-06-04 20:49:45 · 1704 阅读 · 0 评论 -
学习笔记-大型网站架构演变过程
1、Web服务器(Http服务器 + 应用服务器)和数据库部署在同一个服务器主机上。此时,web服务器和数据库在处理业务时可能会互相限制。因此将web服务器和数据库分放在不同的主机上。结论:不满足服务器设计的高可用性目标, 因为无论是web服务器还是数据库出现问题,都会影响另一端。2、浏览器的请求分为静态资源请求(HTML页面、js脚本、css和img请求)和动态资源请求( jsp/php...原创 2019-06-18 16:10:49 · 326 阅读 · 0 评论 -
C++ Socket网络编程 解决网络阻塞和粘包\少包的问题(客户端)
在当前的版本中,实现了简易TPC的客户端和服务端程序,实现的功能有客户端对服务端进行连接,输入命令并接收回复等。那么当前的程序中,网络传输数据主要由手动输入数据来提出需求,并且每次传输的数据也很小。这导致网络吞吐量十分的小,因此能够很好的实现功能。但事实上,当把每次传输的数据的大小提高,并且由程序循环发送和接收数据时,会面临网络阻塞的问题。如下图:在网络传输的过程中,Socket底层定义了...原创 2019-04-09 15:31:11 · 3067 阅读 · 3 评论 -
C++Socket 多线程编程 服务端1.7版本 多线程分组处理多客户端
之前在处理客户端多个socket连接服务端的程序运行时,例如1000个客户端;这1000个客户端socket连接到服务端需要花费相当长的时间。因此,本节对服务端的程序进行改进,使接受连接的select业务和接受发送数据的select业务分开。1、生产者和消费者模型生产者线程处理客户端连接的请求,并将新接入的客户端socket安排到消费者线程的处理队列中。消费者线程,每个线程增加一个消息队列...原创 2019-04-15 22:15:28 · 1225 阅读 · 5 评论 -
C++ Socket网络编程 简易客户端1.0版本搭建(二)
接上节 搭建网络通信客户端代码(2) 用Socket API建立简易的TCP客户端建立一个Socket连接服务器 connect接受服务器信息 recive关闭 socket废话不多说,与服务端类似,直接上代码。SOCKET编程 可以在每一步都判断是否成功建立、连接或监听 从而提高代码的鲁棒性#define WIN32_LEAN_AND_MEAN#define _WINSOC...原创 2019-04-05 10:13:47 · 383 阅读 · 0 评论 -
C++ Socket网络编程 简易服务端和客户端1.1版本改进(三)
上一个版本只是 简单的搭建了 TCP 服务端和客户端程序因此在此基础上继续升级 以开发更多的功能在1.0版本中 服务端通过while循环 等待新客户端的连接 在1.1的版本中 希望能让服务端持续处理客户端发送的请求1、 改造服务端程序前四步不需改变(1)建立socket (2)绑定端口 (3) 监听端口 (4)等待客户端链接接着是循环接受 (5)客户端发送的请求 (6)处理客户端发送的...原创 2019-04-05 14:54:10 · 436 阅读 · 0 评论 -
C++ Socket网络编程1.2版本 发送结构化的网络消息数据和网络数据报文
目前的版本中,客户端和服务端的网络通信 实现了简单的逻辑:(1)客户端发送请求(字符串)到服务端 (2)服务端处理请求(字符串) (3)服务端返回处理结果(字符串)本节没有改进客户端和服务端的业务逻辑,而是改进字符串的消息传递,构建结构化的网络消息,使网络传输功能更复杂。**使用结构体定义结构化的网络消息**在客户端和服务端程序代码中定义结构体//一定要保证服务端和客户端(操作系统...原创 2019-04-05 17:26:49 · 843 阅读 · 0 评论 -
C++ Socket网络编程1.2版本 多次收发报文升级为一次收发
在目前的版本中,将网络数据传输方式改进成为网络数据报文(结构体)的形式传输,但比较不合理的一点是,传输数据的过程中总是要先传输 包头,再传输包体。因此,本节将多次收发报文改进为一次收发报文。再回顾一下上一节的关键内容:1、定义了四个网络数据包结构体//DataPackgestruct Login{ char userName[32]; char Password[32];};st...原创 2019-04-06 09:54:00 · 685 阅读 · 4 评论 -
C++ Socket网络编程1.2版本 网络报文结构消息头的DataLength的作用
在当前的版本中,服务端和客户端的收发报文都是 固定长度的数据 且是在本地网络运行,因此粘包和少包的情况还未出现。那么dataLength的作用在目前版本中的作用很小。但当网络收发数据是变长数据的时,例如发送的是图片文件,dataLength的作用是告知收发文件的大小。本节对服务端和客户端的收发逻辑进行简单改进,以使用dataLength提供的长度进行收发。对服务端的收发逻辑做如下更改: ...原创 2019-04-06 10:56:08 · 826 阅读 · 0 评论 -
C++ Socket网络编程 1.3版本 将服务端升级为Select模型处理多客户端
在之前的版本(1.1和1.2)中,服务端和客户端都是1对1的阻塞模型网络程序,例如服务端的accept,recv都是阻塞等待。一个最大的问题是,当服务端阻塞时,不能处理其它的业务,从而无法实现一个服务端处理多个客户端的功能。因此,将服务端升级为Select模型处理多客户端的网络请求。Select网络模型是Linux、Windows、IOS、安卓等操作系统中标准C/C++支持的网络通信模型,内部会...原创 2019-04-06 12:12:07 · 589 阅读 · 1 评论 -
C++ Socket网络编程 1.3版本 将服务端升级为非阻塞Select模型
根据上节所示,select函数的最后一个参数设置为了NULL,这表明此时的select函数是阻塞形式的。因此,本节通过改造select函数的最后一个参数,使它成为非阻塞形式,以处理更多的逻辑业务。select的定义:select( _In_ int nfds, _Inout_opt_ fd_set FAR * readfds, _Inout_opt_ fd_set F...原创 2019-04-07 10:06:57 · 293 阅读 · 0 评论 -
C++ Socket网络编程 1.3版本 将客户端升级为Select模型
本节将要实现的功能是:当有客户端程序连接到服务端时,服务端通知所有客户端,有新的客户端加入。首先增加一个消息命令和消息结构体:enum CMD{ CMD_LOGIN, CMD_LOGIN_RESULT, CMD_LOGINOUT, CMD_LOGOUT_RESULT, CMD_ERROR, CMD_NEWUSERJOIN,};struct NewUserJoin :publi...原创 2019-04-07 11:10:12 · 392 阅读 · 0 评论 -
C++ Socket网络编程 1.3版本 在客户端中加入多线程 实现输入功能
在改造客户端为select网络模型的时候,由于C++的标准输入流函数cin是阻塞函数,因此暂时将其删掉。本节引入线程,与主线程分离的处理客户端的输入命令逻辑业务。编写一个函数,用于客户端循环输入命令,并send给服务端处理。bool g_bRun = true; //全局变量,用于控制客户端程序是否结束,如果这个值是false,那么主线程应该结束运行。因此,主线程中,循环进行select函数...原创 2019-04-07 15:16:39 · 333 阅读 · 0 评论 -
C++ Socket网络编程 1.4版本 将客户端程序移植到Linux操作系统
首先将windows下客户端的代码贴入到Linux#define WIN32_LEAN_AND_MEAN#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#include<Windows.h>#include<WinSock2.h>#include<iostream&...原创 2019-04-08 15:56:45 · 326 阅读 · 0 评论 -
C++ Socket网络编程 1.5版本 使用C++面向对象编程对客户端进行改进
客户端连接多个服务端,或者服务端连接其它服务端,或者是交叉的应用。那么这时,使用C语言的方式编写代码是不合适的。使用类去封装服务端和客户端功能,使其更加易用。本节对客户端进行封装,一个客户端程序能够支持连接多个服务器。(在实际的开发中,这种情况是必然存在的。有可能一个客户端需要连接登陆数据库、业务处理服务器等);新建一个EasyTcpClient.hpp文件,对类的定义和实现都写在同一个文件...原创 2019-04-08 21:42:13 · 395 阅读 · 0 评论 -
C++ Socket网络编程 1.5版本 使用C++面向对象编程对服务端进行改进
本节实现用C++的面向对象编程来封装服务端的业务逻辑。面向对象编程的优点这里就不赘述了,封装后的类可以使业务逻辑更清晰,完成复杂的功能更容易。基本实现的方法没有太多改变,只是讲服务端Socket通信的每个步骤封装到了类中。OnRun函数用于Select网络模型请求判断。在后续的改进中,可以将为类添加更多的成员变量或成员函数,或者构造派生类,实现不同的业务逻辑。class EasyTcpSer...原创 2019-04-09 10:29:54 · 451 阅读 · 0 评论