谈谈游戏服务器的发送数据处理

发送数据处理模式的概念:

 相信每一个第一次写游戏服务器的人都会在发送数据处理这里卡主,因为相对于简单易处理的接收消息处理,发送消息的时机和驱动更加难以把握。为什么呢?我们看下套接字可读的条件:

 1: 该套接字接收缓冲区中的数据字节数大于接收低水位标记

 2: 该连接的读关闭

 3: 该套接字是一个监听套接字,并且有新的连接

 4: 该套接字上有错误处理

以上所有的条件,都可以通过注册事件来完成,并且因为都是被动触发,所以处理起来比较轻松。

那我们看看套接字可写的条件:

 1: 该套接字发送缓冲区中可用空间大于发送高水位标记

 2: 该套接字的写关闭

 3: 该套接字上有错误处理

看到套接字可写的条件我们为难了,因为我们需要发送的时候,套接字并不一定可写;而套接字可写的时候,我们未必有数据要发送,这就造成了事件的浪费,也就造成了发送数据比接收数据更难。

 

前言: 我们在这里是将网络数据的发送和接收放在单独的线程里面处理,称之为网络IO线程;而在其他的线程总处理玩家逻辑,称之为玩家逻辑线程。

 

解决方案1: 定时发送。

定时发送算是一个比较通用的处理,也是用起来比较方便的方式。对于每一个来自客户端的连接,我们只是注册可读事件,而不会注册可写事件,对于发送处理,我们采用定时器触发的模式,比如每一个连接上绑定一个30ms的定时器,每次定时器触发的时候,也就是写饥饿的时候,对每个连接都去做一次试图发送的处理。

当大家看到思路的时候,我想麻烦也就跟着来了。因为是30ms的定时器,所以每条消息的延迟都是N*30ms;可能很多的套接字并没有数据要发送,但是定时器到了,造成了很多浪费;因为定时器的触发也是轮训的模式,大家不是都说“轮训就是强奸吗”。

 

解决方案2: 按需注册write事件

 如果我们真正了解write事件,就应该按需注册write事件。每次发送玩家数据的时候,如果只发送了部分数据,则把剩余的数据存放到自定义缓冲区,并且注册write写事件;这个事件会在下一次select的时候触发,触发的时候发送剩余的数据,如果发送完毕,就关闭write事件。

 这里我们分开网络io线程和游戏逻辑线程,如果是网络io线程内部发送数据,那么很简单,只需要调用提供send函数就可以了。如果是游戏逻辑线程里发送数据,就会稍微麻烦一点。为了保证线程的安全性以及数据的完整性,在游戏逻辑线程里面调用发送数据的接口,实际的工作是在网络线程里面完成。简单来说就是将这个函数或者task,投递到网络io线程里面去执行。

我们可以参考下muduo的做法,如果是在非网络io线程里面发送数据,就将要发送的套接字和数据封装成Functor,投递到网络io线程中去,并且唤醒网络IO线程,去处理这些需要执行的Functors(std::vector<Functor>)。

我在修改自己的网络发送模式的时候,也是这个思路,不过是用的是java为多线程提供的FutureTask,如果是在非网络io线程中发送数据,就将需要发送的连接和数据封装成FutureTask,投递到网络Io线程中去,唤醒io线程,处理需要执行的FutureTasks(Vector<FutureTask>)。

好吧,最后还是承认,其实在设计的时候,参考了一下mina的设计,不过看到muduo网络库居然和mina 的设计如此类似,相比muduo的设计也是参考了mina的设计。

 

可能很多人认为方案2的方案,会增加系统调用。因为我们不是总说要减少系统调用吗。这也是定时器发送数据模式的依据,可是我们的tcp已经提供了negle算法,大部分send的函数,只是将数据写入到缓冲区,并没有那么大的消耗。大家可以测试看下!

时间: 2024-12-23 04:22:05

谈谈游戏服务器的发送数据处理的相关文章

游戏服务器的发送数据处理

发送数据处理模式的概念: 相信每一个第一次写游戏服务器的人都会在发送数据处理这里卡主,因为相对于简单易处理的接收消息处理,发送消息的时机和驱动更加难以把握.为什么呢?我们看下套接字可读的条件: 1: 该套接字接收缓冲区中的数据字节数大于接收低水位标记 2: 该连接的读关闭 3: 该套接字是一个监听套接字,并且有新的连接 4: 该套接字上有错误处理 以上所有的条件,都可以通过注册事件来完成,并且因为都是被动触发,所以处理起来比较轻松. 那我们看看套接字可写的条件: 1: 该套接字发送缓冲区中可用空

游戏服务器开发中的一点值得注意的地方

     一年前一直是做C++游戏服务器的开发工作,后来被接手了一个java的服务器,也就开始写java了,本来就没有什么基础,就赶紧买来了基本java的编程书,<java 编程思想>,<Effective java>等等.在Effective java中有一条就是"返回0长度的数组,而不是null".那么我们就借助一段代码来谈谈这一条.       我们将这一条扩展一下,就是返回0长度的容器,而不是null;       我们还可以再扩展一下,就是传递0长度的

阿里云游戏服务器价格-阿里云游戏服务器多少钱

本文详细介绍阿里云游戏服务器的价格以及如何通过优惠的方法购买阿里云游戏服务器. 首先介绍下阿里云游戏服务器 阿里云针对游戏而推出的高性能服务器,配备游戏盾和Ddos高防IP构建最强游戏安全防护体系,轻松防御百G级别Ddos攻击以及各种应用层攻击.阿里云的游戏专用服务器,以其高稳定,高可用性以及强大的防护能力,正日益受到游戏开发,及游戏运营等游戏行业人员的青睐. 游戏是目前最热门的一个行业,所以也导致了该行业竟争的日益激烈.在游戏运行初期,只需投入一小部分费用,用于游戏服务器的购买.但游戏服务器在

棋牌游戏服务器基本架构

1. 总体设计概述休闲游戏系统主要包括以下几个部分: l 服务器:CenterServer.GameDataServer.GameServer.LoginServer l 客户端 l 数据库 l 网管工具 l 网页服务器 用户使用客户端通过网络连接LoginServer进行身份验证,CenterServer和GameServer通过数据库存取用户数据,客户端和GameServer配合完成用户的游戏功能,网管工具用来管理服务器的配置.启动等工作,网页服务器提供相关网页处理. 2. 各部分的主要功能

cardstories 1.0.4发布 网络猜谜游戏服务器图片卡

cardstories提供了一个网络猜谜游戏服务器使用的图片卡.一个玩家开始通过选择卡,选择一个词或一个句子来形容它,并发送邀请函给他人参加比赛.这些球员每收到七张牌,并挑选一个最符合的描述.一旦足够的玩家选择了一张卡片,笔者选择显示卡和所有的玩家揣摩哪一个是作者.如果至少有一个但不是所有的猜测都正确,哪么作者胜,随着玩家被谁猜中.最后,猜测的将全部获胜. cardstories 1.0.4此版本在"get_package"功能的性能得到改善.在"数据库:database_a

游戏服务器架构演进(完整版)

一.游戏服务器特征 游戏服务器,是一个会长期运行程序,并且它还要服务于多个不定时,不定点的网络请求.所以这类服务的特点是要特别关注稳定性和性能.这类程序如果需要多个协作来提高承载能力,则还要关注部署和扩容的便利性;同时,还需要考虑如何实现某种程度容灾需求.由于多进程协同工作,也带来了开发的复杂度,这也是需要关注的问题. 功能约束,是架构设计决定性因素.基于游戏业务的功能特征,对服务器端系统来说,有以下几个特殊的需求: 游戏和玩家的数据存储落地 对玩家交互数据进行广播和同步 重要逻辑要在服务器上运

用lua_tinker将lua脚本嵌入到游戏服务器

      忙中偷闲,经过几天的努力,将lua脚本嵌入到系统中.之前公司的时候,偌大一个服务器全部使用C++编写,对于新手经常发生一些宕机事件,被主程责骂.在后来接触的一些人中,发现很多公,都已经引入lua来适应多变的环境和敏捷开发!正如一个主程所说的,在n年前网易已经脚本为王了,现在很多公司拿着C++不放,作为开发人员不苦逼才怪! 想想在广州开发游戏的日子,每次在群里面看到运维说某某服务器上面有coredump文件时,总是惊出冷汗,赶紧用gdb去查询,是哪行代码引起的宕机:还要应对主程的责骂!

iocp-C# IOCP模式下服务器主动发送消息

问题描述 C# IOCP模式下服务器主动发送消息 http://blog.csdn.net/zhujunxxxxx/article/details/43573879 服务器端代码是参考这篇帖子的. 我想要实现,按下按钮,然后往所有当前连接上的客户端发送数据. 但是从SocketAsyncEventArgsPool 对象池里pop一个SocketAsyncEventArgs e,然后发送数据. 发送函数里的Socket s = e.AcceptSocket会出现未实例化的错误. 发送函数如下 pu

gameserver-有谁有弄过手机游戏服务器人民币充值模块,求指教??

问题描述 有谁有弄过手机游戏服务器人民币充值模块,求指教?? 有没有谁弄过手机游戏上人民币充值这一块,求了解? 就是本地服务器跟苹果和安卓的服务器进行相关联.还有需要处理哪些步骤?? 比如说查找哪些资料,如何查找资料,求大神们帮帮忙!!!!本地服务器是用C++来实现的. 还有这些事哪些步骤??