网络游戏探索(ing

简述

一个验证游戏开发中,常用网络架构的demo

  • 弱联网(http链接):排行榜功能
  • 即时性较弱(基于tcp):多人大厅,聊天室
  • 及时性强(基于udp):房间类,多人格斗

demo框架:

unity(URP + xlua + VMUI)
网络层使用udp,客户端使用xlua集成的luasocket,服务端使用c++


一 即时格斗部分(及时性)

概述

使用udp+帧同步,保证传输效率和准确性

服务端代码:

#include 
#include 

#include 
#include 

#include
#include 
using namespace std;

#pragma comment(lib,"ws2_32.lib")

#define bufsize 1024 
#define UserNum 2       //玩家数量

int main()
{

    //1 创建套接字 绑定端口
    WSADATA wsaData;
    SOCKET sockServer;
    SOCKADDR_IN addrServer;
    SOCKADDR_IN tempClientAddr;

    map strMap;

    SOCKADDR_IN ClientAddrList[UserNum] ;

    int str_len ;
    char message[bufsize] = "\0";
    int     nRet;
    int     len = sizeof(SOCKADDR);

    WSAStartup(MAKEWORD(2, 2), &wsaData);
    sockServer = socket(AF_INET, SOCK_DGRAM, 0);
    addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//INADDR_ANY表示任何IP
    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(6000);//绑定端口6000
    nRet = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
    if (SOCKET_ERROR == nRet)
    {
        printf("bind failed !/n");
        closesocket(sockServer);
        WSACleanup();
        return -1;
    }


    int key = 0;

    //2 进入循环接收玩家信息 与发送信息
    printf("服务器已启动udp:\n监听中...\n");
    while (true)
    {
            str_len = recvfrom(sockServer, message, bufsize, 0, (SOCKADDR*)&tempClientAddr, &len);
            if (SOCKET_ERROR != str_len )
            {
                printf("recv 读入玩家id: %d \n", key);
                ClientAddrList[key] = tempClientAddr;
            }

        for (int i = 0; i < UserNum; i++)
        {
            str_len = sendto(sockServer, message, bufsize, 0, (SOCKADDR*)&ClientAddrList[i], len);
            if (SOCKET_ERROR != str_len)
            {
                printf("send 发送至玩家id: %s\n", message);
            }
        }
    }

    WSACleanup();
}

客户端代码:

-- Assets\LuaScripts\FrameWrok\net\networkmanger.lua
--------------------------------------------
-- @协议 使用udp
--1
function SocketInit()  
    _G["G_SOCKETTCP"] = require("socket.core").udp()
    _G["G_SOCKETTCP"]:settimeout(0)
    SocketSend("20180625")  
end

function SocketClose()  
    _G["G_SOCKETTCP"]:close()  
end  

function SocketSend(sendStr) 
    print("[c->s]:".. sendStr)
    local sendstr = _G["G_SOCKETTCP"]:sendto(sendStr, "127.0.0.1", 6000)
end  

function SocketReceive(callfun)  
    if nil == _G["G_SOCKETTCP"] then return end
    local response, receive_status = _G["G_SOCKETTCP"]:receive()  
    if receive_status ~= "closed" then  
        if response then  
            print("[s->c]:".. response)
            callfun(response)
        end  
    else  
        print("Service Closed!")  
    end  
end 


-- Assets\LuaScripts\FrameWrok\funcTest.lua
local test = {}

---- 网络模块测试 ----
print("网络模块测试------------->Socket")
require("FrameWrok.net.networkmanger")
SocketInit()
SocketSend("player1")

test.update = function ()
    SocketReceive(function (command_str)
        -- print("SocketReceive command_str------------>" .. command_str)
    end) 
end

-- SocketClose()
---- end 网络模块测试 ----

return test

你可能感兴趣的:(网络游戏探索,udp,游戏开发)