网络游戏的前后端通讯(一)

网络游戏的前后端通讯(一)

【旧博客转移 - 发布于2015年9月14日 22:25】

通讯是网络游戏的最重要部分之一,好的游戏通讯协议设计包括一下特点:包体积小、解析速度快、支持加解密等等,下面就简单说一下通讯协议的设计

1.游戏中常用的通讯协议以及数据格式

HTTP:

早期的SLG游戏一般会采用HTTP协议进行通讯,后端大多采用PHP,通讯格式用XML、JSON等字符串,由于HTTP是短链接,所以没办法做到服务端主动更新数据推送给客户端,那种需要实时更新的数据,一般都采用客户端定时请求来实现。

Tcp/IP:

随之MMO游戏兴起,对游戏实时交互的要求越来越高,Tcp这种长连接协议被广泛采用,通过Socket接口,我们可以跟服务端建立起长连接,这种双向连接很方便实时交互以及服务端主动推送数据,基于这种协议的通讯格式可以是XML、JSON,但大部分都采用直接把对象序列化成二进制的方式传输。常用的二进制序列化格式有AMF(Adobe公司创造)、protobuf(谷歌创造)。protobuf由于包体积小,解析速度快等优势被广泛使用,当然也可以自己去实现一套通讯格式。

2.自定义格式的序列化跟反序列化

序列化就是把一个对象以某种形式编码成二进制,用于存储或者传输。

反序列化顾名思义就是把二进制数据解码成对象。

复合型数据(自定义对象)都会由一些基本数据类型组成,我把它们分为固定长度型跟动态长度型

固定长度如:

byte(8位), short(16位), int(32位), float(32位), long(64位), boolean(8位)

不固定长度:

String, Array

下面是一个把基础类型转换成二进制的工具类,String类型的话就要先写长度再写UTF数据

1 package com.util;

2

3 import java.io.ByteArrayInputStream;

4 import java.io.ByteArrayOutputStream;

5 import java.io.IOException;

6 import java.io.UnsupportedEncodingException;

7 /**

8 * 二进制工具类

9 * @author lijia

10 */

11 public class ByteArrayUtil {

12

13 /**

14 * 把字符串转换成byte[]

15 * @param str 字符串

16 * **/

17 public static byte[] writeUTF(String str){

18 ByteArrayOutputStream byteArr = new ByteArrayOutputStream();

19 byte[] rb = null;

20 try {

21 if(str == null || str == ""){//字符串为空

22 byteArr.write(writeInt(0));//写入长度为0

23 }else{

24 byte[] strbyte = str.getBytes("UTF-8");

25 byteArr.write(writeInt(strbyte.length));//写入字符串长度

26 byteArr.write(strbyte);//写入字符串二进制数据

27 }

28 rb = byteArr.toByteArray();

29 byteArr.close();

30 } catch (UnsupportedEncodingException e) {

31 e.printStackTrace();

32 } catch (IOException e) {

33 e.printStackTrace();

34 }

35 return rb;

36 }

37

38 /**

39 * 读取字符串

40 * **/

41 public static String readUTF(ByteArrayInputStream ips){

42 int strLen = readInt(ips);//先读长度

43 String str = "";

44 if(strLen>0)

45 try {

46 byte[] strByte = new byte[strLen];

47 ips.read(strByte, 0, strLen);

48 str = new String(strByte, "UTF-8");

49 } catch (UnsupportedEncodingException e) {

50 e.printStackTrace();

51 }

52 return str;

53 }

54

55 public static byte[] writeLong(long s) {

56 byte[] buf = new byte[8];

57 for (int i = 8 - 1; i >= 0; i--) {

58 buf[i] = (byte) (s & 0x00000000000000ff);

59 s >>= 8;

60 }

61 return buf;

62 }

63

64 public static long readLong(ByteArrayInputStream ips){

65 byte[] buf = new byte[8];

66 ips.read(buf, 0, 8);

67 long r = 0;

68 for (int i = 0; i < 8; i++) {

69 r <<= 8;

70 r |= (buf[i] & 0x00000000000000ff);

71 }

72 return r;

73 }

74

75 public static byte[] writeInt(int s) {

76 byte[] buf = new byte[4];

77 for (int i = 4 - 1; i >= 0; i--){

78 buf[i] = (byte) (s & 0x000000ff);

79 s >>= 8;

80 }

81 return buf;

82 }

83

84 public static int readInt(ByteArrayInputStream ips) {

85 byte[] buf = new byte[4];

86 ips.read(buf, 0, 4);

87 int r = 0;

88 for (int i = 0; i < 4; i++) {

89 r <<= 8;

90 r |= (buf[i] & 0x000000ff);

91 }

92 return r;

93 }

94

95 /****

96 * 连接两个字节数组

97 * @param b

98 * @param b2

99 * @return

100 */

101 public static byte[] connectByteArray(byte[] b, byte[] b2){

102 int blen = b.length;

103 int b2len = b2.length;

104 byte[] nb = new byte[blen+b2len];

105 for(int i = 0; i < blen; i++){

106 nb[i] = b[i];

107 }

108 for(int i = 0; i < b2len; i++){

109 nb[blen+i] = b2[i];

110 }

111 return nb;

112 }

113 }

下面这个P_User的类包含三个属性:id,age,isVip两个函数:ToBinary按照一定的顺序把对象的各个成员属性转换成二进制写入流中

FromBinary按照顺序把二进制转换成真实数据

package com.coolProto;

public class P_User extends Message

{

public P_User()

{

}

public int age;

public double id;

public boolean isVip;

@Override

public void ToBinary(MessageOutputByteArray osData)

{

write_int(osData, this.age);

write_double(osData, this.id);

write_boolean(osData, this.isVip);

}

@Override

public void FromBinary(MessageInputByteArray isData)

{

this.age = read_int(isData);

this.id = read_double(isData);

this.isVip= read_boolean(isData);

}

}

这样就可以序列化一个对象了,当然这种类可以写一个工具自动生成。用XML做配置属性名,属性类型,值(数组类型用)

这是之前写过的一个工具,用来编辑这种XML配置,支持编译成三种格式(As3、c#、Java)待续...

🌸 相关推荐 🌸

如何将VCF文件导入手机通讯录:全机型详细指南
bt365体育在线官网

如何将VCF文件导入手机通讯录:全机型详细指南

📅 08-12 👀 4736
多种胎位图全解,了解宝宝是哪种胎位
365bet足球论坛

多种胎位图全解,了解宝宝是哪种胎位

📅 06-28 👀 5543
世俱杯|15日上午8点开幕,32强厮杀,这些对决不容错过
外勤365下载安装版本

世俱杯|15日上午8点开幕,32强厮杀,这些对决不容错过

📅 07-19 👀 6841