RakNet Client和公网Server通信 例子 -- 修改远程电脑时间

               

前言:

很多游戏引擎都是不带网络操作的,比如Cocos2d-x ,那我们只好自己去写或者使用现有的,技术有限的我们只能用现有的了。

RakNet是一个开源的C语言网络操作库,被广泛应用于各种网络程序中,当然我这里只关注手机网络游戏。。。。

这算是RakNet的入门一个例子。


本文适合对RakNet有一定了解的朋友


Client 可以直接指定Server 端的IP地址进行连接,从而发送消息、数据到服务端。但是服务端接收到客户端的消息后怎么回复客户端?


其实Server端和Client端发送消息数据都是同样的操作,只是获取消息目的地址的方式不一样。


Server端通过

pPacket->systemAddress

获取到Client 的地址!


下面是完整的例子。


(1) Client 端


MyClient.h

#pragma once#include <iostream>#include "RakPeerInterface.h"   // RakNet Peer#include "RakNetTypes.h"      #include "MessageIdentifiers.h" // RakNet自定义消息枚举定义处#include "BitStream.h"         // RakNet消息包的Bit数据流#define MAX_CLIENTS 10#define SERVER_PORT 60000enum ChatMessagesDefine{// 自定义消息枚举值,消息ID MSG_CHATWORD = ID_USER_PACKET_ENUM + 1,        // 消息ID从RakNet定义的最后一个枚举开始};

main.cpp

#include "MyClient.h"#include <string>#include <sstream>#include <iostream>#include "RakSleep.h"using namespace std;int main(void)/*设置变量控制是否服务器已经返回操作结果*/ bool serverHaveSendBack=true; RakNet::RakPeerInterface *pPeer = RakNet::RakPeerInterface::GetInstance(); RakNet::SocketDescriptor sd; pPeer->Startup(1,&sd, 1); std::string ipAddrStr; cout<<"输入ip:"cin>>ipAddrStr; //作为客户端连接,连接到主机ip地址和端口号 pPeer->Connect(ipAddrStr.c_str(), SERVER_PORT, 0, 0); string timeStrArray[6]={"10:00","11:59:58","19:59:58","20:04:58","20:29:58","23:59:55"}; float k = 0int i=0while(1) {  cout<<"改变时间:[0] 10:00  -  [1] 11:59:58  -  [2] 19:59:58  - [3] 20:04:58   [4]  20:29:58  [5] 23:59:55"<<endl;  int chooseTime;  cin>>chooseTime;  std::string time=timeStrArray[chooseTime];  cout<<"将改变时间为:"<<time<<"  !!"<<endl;  string timeStr=time;  string changeTimeCmd=string("time")+timeStr;  //给主机发送数据  RakNet::BitStream bsOut;  bsOut.Write((RakNet::MessageID)MSG_CHATWORD);  std::ostringstream format_messege;  format_messege <<timeStr;    //输入信息到字符串流  bsOut.Write(format_messege.str().c_str());  pPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,RakNet::UNASSIGNED_SYSTEM_ADDRESS,true);  Sleep(500);  serverHaveSendBack=false;  /*等待服务器返回数据*/  RakNet::Packet* pPacket;  while(!serverHaveSendBack)  {   RakSleep(30);   for (pPacket=pPeer->Receive();pPacket;pPeer->DeallocatePacket(pPacket),pPacket=pPeer->Receive())   {    switch ( pPacket->data[0] )    {    case MSG_CHATWORD:     {      RakNet::RakString rs;      RakNet::BitStream bsIn(pPacket->data,pPacket->length,false);      bsIn.IgnoreBytes(sizeof(RakNet::MessageID));      bsIn.Read(rs); //提取我自定的字符      istringstream input_str(rs.C_String());      string serverBackStr;      input_str>>serverBackStr;      cout<<"Server返回消息: "<<serverBackStr<<endl<<endl;      serverHaveSendBack=true;     }     break;    default:     break;    }   }  } } //断开连接,这个会给对方发送一个消息,告诉它要断开连接了。 pPeer->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(pPeer); return 0;}

(2) Server 端


MyChatServer.h 

#pragma once#include <iostream>#include "RakPeerInterface.h"   // RakNet Peer#include "RakNetTypes.h"       #include "MessageIdentifiers.h" // RakNet自定义消息枚举定义处#include "BitStream.h"          // RakNet消息包的Bit数据流#define MAX_CLIENTS 10#define SERVER_PORT 60000enum ChatMessagesDefine{// 自定义消息枚举值,消息ID MSG_CHATWORD = ID_USER_PACKET_ENUM + 1,        // 消息ID从RakNet定义的最后一个枚举开始};

main.cpp

#include "MyChatServer.h"#include <string>#include <iostream>#include <sstream>#include "RakNetTypes.h"  using namespace std;int main()//给服务器端创建一个实例 RakNet::RakPeerInterface* pPeer = RakNet::RakPeerInterface::GetInstance(); if ( NULL == pPeer ) {  std::cout << "RakNet::RakPeerInterface::GetInstance() Error!" << std::endl;  return -1; } else {  std::cout << "———MyChatServer Init Success(C)———–" << std::endl; } RakNet::Packet* pPacket; std::cout << "Start Server ……" << std::endl//启动服务器 pPeer->Startup( MAX_CLIENTS, &RakNet::SocketDescriptor( SERVER_PORT, 0 ), 1 ); //设置最大链接数 pPeer->SetMaximumIncomingConnections( MAX_CLIENTS ); // while (1) {  for ( pPacket = pPeer->Receive(); pPacket; pPeer->DeallocatePacket( pPacket ), pPacket = pPeer->Receive() )  {   switch ( pPacket->data[0] )   {   case ID_REMOTE_DISCONNECTION_NOTIFICATION:    std::cout << "Another client has disconnected" << std::endl;    break;   case ID_REMOTE_CONNECTION_LOST:    std::cout << "Another client has lost the connection"<< std::endl;    break;   case ID_REMOTE_NEW_INCOMING_CONNECTION:    std::cout << "Another client has connected" << std::endl;    break;   case ID_CONNECTION_REQUEST_ACCEPTED:    {     std::cout << "Our connection request has been accepted" << std::endl;     RakNet::BitStream bsOut;     bsOut.Write( ( RakNet::MessageID )MSG_CHATWORD );     bsOut.Write("Hello world");     pPeer->Send( &bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, pPacket->systemAddress, false );    }    break;   case ID_NEW_INCOMING_CONNECTION:    {     std::cout << "A connection is incoming" << std::endl;     std::string clientIpAddr=pPacket->systemAddress.ToString(true);     std::string GUID=pPacket->guid.ToString();     UINT clientPort=pPacket->systemAddress.GetPort();     cout<<"clientIpAddr= "<<clientIpAddr<<"  GUID= "<<GUID<<endl;    }    break;   case ID_NO_FREE_INCOMING_CONNECTIONS:    std::cout << "The server is full"<< std::endl;    break;   case ID_DISCONNECTION_NOTIFICATION:    std::cout << "A client has disconnected"<< std::endl;    break;   case ID_CONNECTION_LOST:    std::cout << "A client lost the connection" << std::endl;    break;    //用户自定义数据包   case MSG_CHATWORD:    {     RakNet::RakString rs;     RakNet::BitStream bsIn( pPacket->data, pPacket->length, false );     bsIn.IgnoreBytes(sizeof(RakNet::MessageID));     bsIn.Read(rs);    //提取字符串     std::istringstream input_str(rs.C_String()); //存入字符串流     std::string timeStr;     input_str >>timeStr; //提取想要的变量     std::string changeTimeCmd=std::string("time ")+timeStr;     int a= system(changeTimeCmd.c_str());     std::cout << "时间改变为:"<<changeTimeCmd<< std::endl; //打印结果     //给主机发送数据     int connectState= pPeer->GetConnectionState(pPacket->guid);     RakNet::BitStream bsOut;     bsOut.Write((RakNet::MessageID)MSG_CHATWORD);     bsOut.Write("时间改变成功!");     pPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,pPacket->systemAddress,false);    }    break;   default:    std::cout << "Message with identifier %i has arrived" << pPacket->data[0] << std::endl;    break;   }  } } // RakNet::RakPeerInterface::DestroyInstance( pPeer ); return 0;}

最后是程序运行的测试结果:



转载请注明 http://blog.csdn.net/huutu   谢谢!

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值