游戏服务器IP/TCP协议(王者荣耀为例)
第一部分
先分别介绍IP/TCP协议族:
IP协议:
对于TCP/IP网络来说,网络层是其核心所在。该层的IP协议负责生成发往目的地的数据报以实现逻辑寻址,完成数据从网络上一个节点向另一个节点的传输。
IP的主要目的是通过一个互联的网络传输数据报,涉及两个最基本的功能。
●寻址(Addressing):IP协议根据数据报首部中包括的目的地址将数据报传送到目的节点,这就要涉及传送路径的选择,即路由功能。IP协议使用IP地址来实现路由。
●分片(Fragmentation): IP协议还提供对数据大小的分片和重组,以适应不同网络对数据包大小的限制。如果网络只能传送小数据包,IP协议将对数据报进行分段并重新组成小块再进行传送。
IP是一个无连接的、不可靠的、点对点的协议,只能尽力(BestEffort)传送数据,不能保证数据的到达。具体地讲,主要有以下特性。
●IP协议提供无连接数据报服务,各个数据报独立传输,可能沿着不同的路径到达目的地,也可能不会按序到达目的地。
●IP协议不含错误检测或错误恢复的编码,属于不可靠的协议。所谓不可靠,是从数据传输的可靠性不能保证的角度而言的,查询的延误及其他网络通信故障都有可能导致所传数据的丢失。对这种情况,IP协议本身不处理。它的不可靠并不能说明整个TCP/IP协议不可靠。如果要求数据传输具有可靠性,则要在IP的上面使用TCP协议加以保证。位于上一层的TCP协议则提供了错误检测和恢复机制。
●作为一种点对点协议,虽然IP数据报携带源IP地址和目的IP地址,但进行数据传输时的对等实体一定是相邻设备(同一网络)中的对等实体。
IP协议的效率非常高,实现起来也较简单。这是因为IP协议采用了尽力传输的思想,随着底层网络质量的日益提高,IP协议的尽力传输的优势体现得更加明显。
下图是IP数据包的格式:
TCP/UDP协议:
传输层是TCP/IP协议中的非常重要的层次,提供了面向连接的传输控制协议(Transmission Control Protocol,TCP)和无连接的用户数据报协议(User Datagram Protocol,UDP),负责提供端到端的数据传输服务,将任意数据通过网络从发送方传输到接收方。TCP提供的是可靠的、可控制的传输服务,适用于各种网络环境;UDP提供的服务轻便但不可靠,适用于可靠性较高的网络环境。大部分Internet应用都使用TCP,因为它能够确保数据不会丢失和被破坏。本章将对这两种协议进行详细分析。
在OSI模型中,传输层是介于网络层和会话层之间的一个中间层次,弥补高层服务和网络层服务之间的差距,并向高层用户((应用程序)屏蔽通信子网的细节,使高层用户看到的只是在两个传输实体间的一条端到端的、用户可控的、可靠的数据通路。在TCP/IP模型中,由于3个高层简化为1个应用层,传输层是介于网络层与应用层之间的一个层次。
网络层协议提供网络地址、路由、交付功能,而传输层协议提供了端到端数据传输的必要机制。传输层协议通常要负责以下几项基本功能。
●创建进程到进程的通信,进程即正在运行的应用程序。进程之间通过传输层进行通信,发送进程向传输层发送数据,接收进程从传输层接收数据。
●提供控制机制,如流量控制、差错控制。数据链路层定义相邻节点的流量控制,而传输层定义端到端用户之间的流量控制。
●提供连接机制。在数据传输开始时,通信双方需要建立连接。在传输过程中,双方还需要继续通过协议来通信以验证数据是否被正确接收。数据传输完成后,任一方都可关闭连接。
第二部分
下面就以王者荣耀为例说明TCP/IP协议族在网络游戏中的应用。
2.1启动、登录游戏
首先我们启动王者荣耀游戏APP。进人APP资页,第一步会进行版本更新检测。若检查到资源包有更新则进行下载,若未检查到更新的资源包,则本地加载游戏资源包及解压资源包。这期间会跟图片服务器(image.smoba.qq.com),用户信息(game.eve.mdt.qq.com game.str.mdt.qq.com)、数据服务器(down.qq.com,dliedl.qq.com)进行交互,游戏界面加载过程主要是TCP传输。
通过对启动阶段进行抓包分析,游戏启动过程中,客户端通过DNS域名解析获得王者荣耀游戏服务器的IP地址,建立TCP链接,进行数据交互来启动游戏。
2.2游戏对战阶段
在实时对战的过程中,客户端与服务器间主要有两个交互连接,一个为TCP连接,一个为UDP连接。开战(玩家选择自己的英雄角色及技能)及游戏分出胜负(水晶被毁)时,会触发大量UDP包,包数量大于150;正式游戏过程中,终端与主服务器保持UDP和TCP连接。
(1)TCP长连接
游戏客户端与服务器之间建立一个TCP长连接,由终端发起,通过这个TCP长连接进行心跳和其它信息交互,用以确认服务器状态正常,心跳间隔3s,消息大小固定,流程如图1所示:
(2)UDP报文
客户端和服务器之间交互的报文,除了TCP连接报文以外,还有大量的UDP报文,分为两类:
上行UDP报文:客户端通过上行UDP报文将玩家所做的操作上报给服务器。
下行UDP报文:服务器汇总参加对战的所有玩家的操作,通过下行UDP报文广播给参加对战的所有玩家的客户端。
据腾讯消息,王者荣耀游戏采用的同步机制为帧同步(非状态同步),主要流程如下:
1、玩家上报操作。
2、服务器收集各玩家上报的各自操作,进行汇总,以固定的时间间隔(例如60 ms)向参加对方的各玩家广播所有玩家的操作。
令各客户端接收到广播,知道了所有玩家的操作,按照相同的游戏逻辑进行运算,得到相同的结果,呈现在游戏界面上。
通过上述帧同步机制,基本可以保证参加对战的各玩家游戏步调是一致的,即游戏玩家间的显示基本是相同的(因为网络时延的不同会略有差异)。图2王者荣耀游戏帧同步流程:
根据以上分析,总结如下:
一、王者荣耀游戏的启动和登录采用TCP连接,并且游戏交互过程中保持TcP连接通过心跳包(3s间隔)来检测用户是否在线。
二、王者荣耀游戏的客户端操作与界面显示是通过UDP数据流与服务器进行交互的,下行速率最小需80 kbps,上行速率需64 kbps。因此王者荣耀游戏对速率要求较小。
第三部分
推荐一个实现TCP/IP的简单代码。摘自(73条消息) C++:实现socket通信(TCP/IP)实例_Cche的博客-CSDN博客_c++ socket
(1)server端代码
#include "pch.h" #include<iostream> #include<winsock.h> #pragma comment(lib,"ws2_32.lib") using namespace std; void initialization(); int main() { //定义长度变量 int send_len = 0; int recv_len = 0; int len = 0; //定义发送缓冲区和接受缓冲区 char send_buf[100]; char recv_buf[100]; //定义服务端套接字,接受请求套接字 SOCKET s_server; SOCKET s_accept; //服务端地址客户端地址 SOCKADDR_IN server_addr; SOCKADDR_IN accept_addr; initialization(); //填充服务端信息 server_addr.sin_family = AF_INET; server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(5010); //创建套接字 s_server = socket(AF_INET, SOCK_STREAM, 0); if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) { cout << "套接字绑定失败!" << endl; WSACleanup(); } else { cout << "套接字绑定成功!" << endl; } //设置套接字为监听状态 if (listen(s_server, SOMAXCONN) < 0) { cout << "设置监听状态失败!" << endl; WSACleanup(); } else { cout << "设置监听状态成功!" << endl; } cout << "服务端正在监听连接,请稍候...." << endl; //接受连接请求 len = sizeof(SOCKADDR); s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len); if (s_accept == SOCKET_ERROR) { cout << "连接失败!" << endl; WSACleanup(); return 0; } cout << "连接建立,准备接受数据" << endl; //接收数据 while (1) { recv_len = recv(s_accept, recv_buf, 100, 0); if (recv_len < 0) { cout << "接受失败!" << endl; break; } else { cout << "客户端信息:" << recv_buf << endl; } cout << "请输入回复信息:"; cin >> send_buf; send_len = send(s_accept, send_buf, 100, 0); if (send_len < 0) { cout << "发送失败!" << endl; break; } } //关闭套接字 closesocket(s_server); closesocket(s_accept); //释放DLL资源 WSACleanup(); return 0; } void initialization() { //初始化套接字库 WORD w_req = MAKEWORD(2, 2);//版本号 WSADATA wsadata; int err; err = WSAStartup(w_req, &wsadata); if (err != 0) { cout << "初始化套接字库失败!" << endl; } else { cout << "初始化套接字库成功!" << endl; } //检测版本号 if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) { cout << "套接字库版本号不符!" << endl; WSACleanup(); } else { cout << "套接字库版本正确!" << endl; } //填充服务端地址信息 }
(2)client端:
#include "pch.h" #include<iostream> #include<winsock.h> #pragma comment(lib,"ws2_32.lib") using namespace std; void initialization(); int main() { //定义长度变量 int send_len = 0; int recv_len = 0; //定义发送缓冲区和接受缓冲区 char send_buf[100]; char recv_buf[100]; //定义服务端套接字,接受请求套接字 SOCKET s_server; //服务端地址客户端地址 SOCKADDR_IN server_addr; initialization(); //填充服务端信息 server_addr.sin_family = AF_INET; server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(1234); //创建套接字 s_server = socket(AF_INET, SOCK_STREAM, 0); if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) { cout << "服务器连接失败!" << endl; WSACleanup(); } else { cout << "服务器连接成功!" << endl; } //发送,接收数据 while (1) { cout << "请输入发送信息:"; cin >> send_buf; send_len = send(s_server, send_buf, 100, 0); if (send_len < 0) { cout << "发送失败!" << endl; break; } recv_len = recv(s_server, recv_buf, 100, 0); if (recv_len < 0) { cout << "接受失败!" << endl; break; } else { cout << "服务端信息:" << recv_buf << endl; } } //关闭套接字 closesocket(s_server); //释放DLL资源 WSACleanup(); return 0; } void initialization() { //初始化套接字库 WORD w_req = MAKEWORD(2, 2);//版本号 WSADATA wsadata; int err; err = WSAStartup(w_req, &wsadata); if (err != 0) { cout << "初始化套接字库失败!" << endl; } else { cout << "初始化套接字库成功!" << endl; } //检测版本号 if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) { cout << "套接字库版本号不符!" << endl; WSACleanup(); } else { cout << "套接字库版本正确!" << endl; } //填充服务端地址信息 }
相关知识
如何查询王者荣耀游戏服务器ip
网游中的网络编程系列1:UDP vs. TCP
【游戏开发】网络协议及模型
腾讯游戏典型游戏IP运营分析——王者荣耀
我国网络游戏营销策略分析——以《王者荣耀》为例
如何查询手机游戏服务器IP? (查询手机游戏服务器ip)
如何获取手机游戏的服务器IP
传统文化语境下的国产手游发展研究 ——以《王者荣耀》为例
怎么游戏服务器ip(如何找到游戏服务器的IP地址)
如何查看网络游戏服务器IP
推荐资讯
- 1老六爱找茬美女的烦恼怎么过- 4999
- 2博德之门3黄金雏龙法杖怎么得 4869
- 3《大侠立志传》剿灭摸金门任务 4312
- 4代号破晓官方正版角色介绍 4023
- 5赛马娘锻炼到底的伙伴支援卡事 3802
- 6闪烁之光11月兑换码大全20 3774
- 7原神原海异种刷怪路线-原神原 3547
- 8爆梗找茬王厕所特工怎么通关- 3542
- 9《我的世界》领地删除指令是什 3440
- 10原神开局星落湖怎么出去 原神 3426