撸个服务端出来系列(一)

作为一个干了快一年半的客户端。有时候我总是在想游戏的服务端是怎么实现的呢~或者说我要如何撸出一个服务端来呢?

由于之前有做web的经验和大学时写过一个聊天室程序。我想大不了是个实现在tcp上的长连接嘛。

嗯!首先我要实现两端通信(这不是废话嘛)。

我列了下初期要做的工作大致是

1.技术的选型。由于我最熟悉的客户端是cocos2dx,最熟悉的服务端语言是java。ok那拍了下脑袋就用这两个吧。

2.定制一个交互协议。根据我写客户端的经验。一般搞安卓和ios的服务端的人都喜欢丢个xml或者json给你解析。为嘛?简单呗。不过由于我写的是游戏,而且是跨语言的通信xml和json似乎都是还不错的选择。但毕竟咱们这个是带有实践性的技术研究。所以我设计了如下的报文格式。

int 协议号short 消息体长度byte[] google buffer
为啥我采用了google buffer呢。实际上我是为了偷懒。你要知道如果我每个协议都定义了一个具体的消息体结构。那我就要把它翻译成两种语言。无疑在效率上是很傻逼的一件事,而且根据我的实际开发经验,往往协议翻译出错,导致的问题要么很容易排查,要么很难找到问题。而且google buffer的原理和压缩。可以使得在性能上不是特别下降的情况下,能够压缩我的协议。有兴趣的同学可以学习下google buffer

这里提供一篇IBM原理性的文章

http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

3.跨平台通信的问题解决。有人会问。你不是用google buffer了麽。不过你要知道我的协议号和消息长度两个可不是google buffer。这里我们需要解决1).大小端通信的问题.2)粘包和丢包的处理。这部分可以去参考网上许多的博客。还有Netty的教程(其实我一开始是用mina的。至于为啥不用java socket和nio 因为我一开始写的聊天室,每次都要启动一个线程维护一个session,原来还有多路复用的技术~ ~,至于nio因为即使给我直接用nio我也不一定能很方便的写出东西,在探究东西上和干活效率上总有个平衡点嘛)。

https://github.com/waylau/netty-4-user-guide


在使用Qt编写服务端程序时,可以使用Qt网络模块提供的QTcpServer类来实现一个服务端连接多个客户端的功能。具体实现方法如下: 首先需要在服务端程序中创建一个QTcpServer对象,用于监听客户端的连接请求。可以在服务端程序的构造函数中使用如下代码创建一个QTcpServer对象: ``` m_server = new QTcpServer(this); ``` 然后需要调用QTcpServer对象的listen()函数开始监听客户端的连接请求,例如: ``` if(!m_server->listen(QHostAddress::Any, 1234)) { qDebug() << "Server listen error!"; return; } ``` 上述代码中的端口号1234可以根据实际需求进行修改。如果端口被占用或监听失败,listen()函数会返回false;如果监听成功,返回true。 当服务端监听到一个新的客户端连接请求时,会自动发出newConnection()信号。因此在服务端程序中需要连接这个信号并编写一个槽函数来处理客户端的连接请求,例如: ``` connect(m_server,SIGNAL(newConnection()),this,SLOT(onNewConnection())); ``` 上述代码将服务端的newConnection()信号连接到了名为onNewConnection()的槽函数。 在onNewConnection()函数中需要调用QTcpServer对象的nextPendingConnection()函数来获取一个新的QTcpSocket对象,这个对象代表一个新连接的客户端。这里需要用一个QList对象来保存所有已连接的客户端(QTcpSocket对象)。例如: ``` void MyServer::onNewConnection() { QTcpSocket *socket = m_server->nextPendingConnection(); m_clients.append(socket); } ``` 上述代码中,将新连接的QTcpSocket对象加入到保存已连接客户端的QList对象中。 现在服务端已经连接了多个客户端,可以通过发送和接收数据来与客户端进行通信。具体方法可以参考QTcpSocket类的使用方法。 最后需要注意的是,需要在服务端程序析构函数中将所有已连接的客户端QTcpSocket对象都关闭并从QList中移除,以免出现内存泄漏的问题。例如: ``` MyServer::~MyServer() { foreach (QTcpSocket *socket, m_clients) { socket->close(); m_clients.removeOne(socket); delete socket; } } ``` 上述代码中,遍历已连接的客户端QTcpSocket对象,依次关闭并移除它们,最后删除这些对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值