多人在线游戏架构实战-基于C++的分布式游戏编程开篇

Posted 天杪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多人在线游戏架构实战-基于C++的分布式游戏编程开篇相关的知识,希望对你有一定的参考价值。

学习一门语言很久了,却从来没有用它做过项目,刚学的时候用它来写过一个黑白通讯录,后来又常常用它来刷题。会了Java以后,刷题也不愿意去用这门语言了,没错它就是C++,一把锋利的瑞士军刀。这个国庆节期间,我要定时更新这本《多人在线游戏架构实战-基于C++的分布式游戏编程》的笔记,用来给学生时代的C++留下一个美好的回忆。

本系列笔记的内容均在 deepin 20.7 环境下完成。

2022-10-1

于深圳   

阻塞式网络编程

随书的附录代码在https://github.com/setuppf/GameBookServer,首先就遇到了一个下马威,01-01_network_first的 make-all.sh执行出错。

提示没有cmake3命令,于是安装cmake。

sudo apt install cmake

依然提示没有找到cmake3命令,于是我对第20行做了更改。这是因为原书是在centos下写的,centos是一个很老旧的系统,自带的cmake版本是cmake2,因此centos是 cmake3 命令。在我的deepin上,直接使用cmake就行了。我预感后面可能还会踩到这些坑。

cmake -DCMAKE_BUILD_TYPE=$buildType ./

这一节主要接触到了linux与windows平台下的兼容情况。使用了条件编译来解决,同样的函数名,在不同的OS下有不同的具体实现。

#ifndef WIN32 //如果不是在 Windows 平台下
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> 

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define SOCKET int
#define INVALID_SOCKET -1
#define _sock_init( )
#define _sock_exit( )
#define _sock_err( )	errno
#define _sock_close( sockfd ) ::close( sockfd )
#else //否则在 Windows 平台下
#include <Ws2tcpip.h>
#include <windows.h>
#define _sock_init( )	 WSADATA wsaData; WSAStartup( MAKEWORD(2, 2), &wsaData ); 
#define _sock_exit( )	 WSACleanup(); 
#define _sock_err( )	WSAGetLastError()
#define _sock_close( sockfd ) ::closesocket( sockfd )
#endif //结束条件编译

在 Clion 这个ide下,不执行的部分会自动折叠,这很棒!

书上有个错误,windows下与linux 下的_socket_err 这个函数搞反了。


一些函数

socket 函数,3个参数(family,type,protocol )分别制定ipv4or6,是否是连续可靠,以及TCP/UDP。返回值是一个正数,在连接存续期间,其他程序是不能使用这个特定值的。

bind函数 3个参数(sockid,address,address_len)。第一个是socket的id,第二个是一个套接字地址结构,包含了ip地址和端口。第三个是套接字低级结构的长度

这里的sockaddr为什么可以传入一个 sockaddr_in 的结构体呢,难道类似于Java的向上转型?我看了这个结构没发现“泛型”的标志。其实这是c++比较自由的特点,简而言之,程序员利用类型转换欺骗了编译器。编译器拿着sockaddr_in 为sockaddr 赋值,sockaddr的某个参数需要几个字节,就从冒充的sockaddr_in 里的对应位置拿。

listen 2个参数,分别是socket的id以及缓存连接队列的大小。

accept函数 3个参数,返回一个新的socketID,被称为连接socket。参数分别是原先的 socketID我们称之为监听socket;socketaddr(空的);以及socketaddr的长度。

send和recv函数,这两个函数都有4个参数。分别是:监听socketID;缓存(char数组);缓存的长度;标志位(一般为0)。

网络多人游戏架构与编程

网络多人游戏架构与编程1

1、即使在今天,大多数的多人在线游戏在每个游戏会话中仍然限制玩家的数量 ,一般支持4~32个玩家。然而,在大规模多人在线游戏(massive multiplayer online gmme,MMO)中,成百上千的玩家将同时出现在同一个游戏会话中。

2、《星际围攻:部落》的开发者们最终将数据分为以下4种类型:

  1)非保障数据。当带宽有限时,游戏选择首先丢弃这些数据。

  2)保障数据。

  3)最近状态的数据。只有最新玩家数据才是重要数据的场合。如游戏知道了玩家当前的生命值,那么他5秒之前的生命值就不重要了。

  4)最快保障数据。如一个玩家的移动信息,在一个非常短的时间内极其重要,因此要忙传输。

3、对等网络模型需要O(n^2)的带宽,而C/S模型只需要O(n)带宽。

4、《星际围攻:部落》的网络模型:

  技术图片

  1)平台数据包模块。标准套接字API的封装,可以构建和发送不同的数据包格式。

  2)连接管理器。将网络中两台计算机之间的连接抽象化,连接管理器是不可靠的,它保证投递状态通知的正确传输。

  3)流管理器。决定允许数据传输的最大速率。把请求按优先次序排列好,在带宽限制下,移动管理器、事件管理器、ghost管理器拥有最高优先级。

  4)事件管理器。维持游戏模拟层产生的事件队列,这些事件可以看作是远程过程调用(remote procedure call, RPC)。

  5)Ghost管理器。复制被认为与指定客户端相关的动态对象。这些信息按优先级分为“必须知道的”、“最好知道的”

  6)移动管理器。当有移动数据可用时,流管理器总是给出站数据包添加所有的移动管理器数据。

5、

6、

7、

以上是关于多人在线游戏架构实战-基于C++的分布式游戏编程开篇的主要内容,如果未能解决你的问题,请参考以下文章

游戏服务器架构概要

当我读《网络多人游戏 架构与编程》时我在想什么

多人游戏的服务器架构? [关闭]

项目实战C++多文件写法轻松实现练手小游戏:贪吃蛇

多人在线游戏(MMO)|建筑|学习路径

C++游戏编程教程——项目实战