skynet:udp

skynet 爲 udp 協議做了有限的支持。和 tcp 協議不同,udp 協議不需要阻塞讀取。這是因爲 udp 是不可靠協議,無法預期下一個讀到的數據包是什麼(協議允許亂序和丟包),因此 skynet 的 udp 協議封裝採用的是 callback 的方式。

一、服務端測試

main.lua

local skynet =  require "skynet"
local socket = require "skynet.socket"

local socket_id = nil

function udp_recv(str, from)
        address, port = socket.udp_address(from)

        skynet.error("recv udp data from: " .. address .. ":" .. port .. " data:" .. str)
        socket.sendto(socket_id, from, string.upper(str))
end


skynet.start(function()
		--監聽指定地址
        socket_id = socket.udp(udp_recv, "192.168.255.128", 8003)
        assert(socket_id)
end)
  • socket.udp(function(str, from), address, port) : id

    • 參數一: callback 函數,它會收到兩個參數。str:收到的包內容,字符串類型;from:消息來源的字符串,可用於後續對本條消息的響應地址(見 socket.sendto)
    • 參數二:需要綁定的 ip 地址,字符串,默認爲 ipv4 的 0.0.0.0。
    • 參數三:綁定的端口,數字,若不寫或傳 0,表示僅創建一個 udp handle (用於發送),但不綁定固定端口。
  • socket.udp_address(from) : address port
    將 from 轉換爲可讀的 ip 地址和端口,用於記錄。

測試採用 sokit 作爲客戶端,測試結果如下:
在這裏插入圖片描述
在這裏插入圖片描述

二、客戶端測試

main.lua

local skynet    = require "skynet"
local socket    = require "skynet.socket"

local socket_id = nil

function client(id)

        socket.udp_connect(socket_id, "127.0.0.1", 8003)
        local i = 0
        while(i < 3) do
                socket.write(socket_id, "data"..i)
                skynet.error("send data"..i)
                i = i + 1
        end
        socket.close(id)
        skynet.exit()
end


function udp_recv(str, from)
        address, port = socket.udp_address(from)
        skynet.error("recv udp data from: " .. address .. ":" .. port .. " data:" .. str)

        --socket.sendto(socket_id, from, string.upper(str))
end


skynet.start(function()
        socket_id = socket.udp(udp_recv)

        assert(socket_id)
        skynet.fork(client, socket_id)
end)
  • socket.udp_connect(id, address, port, callback)

    給 id 設置一個默認的發送目的地址,之後就可以用 socket.write 來發送數據包。

    • id:socket.udp() 的返回值;
    • address/port:默認發送地址,當你用 socket.udp 創建出一個非監聽狀態的 handle 時,設置目的地址非常有用。因爲你很難有別的方法獲得一個有效的供 socket.sendto 使用的地址串。
    • callback:同 socket.udp() 第一個參數,可選項,通常應該在 socket.udp 創建出 handle 時就設置好 callback 函數。但有時,handle 並不是當前 service 創建而是由別處創建出來的。這種情況,你可以用 socket.start 重設 handle 的所有權,並用這個函數設置 callback 函數。

注:
handle 只能屬於一個 service ,當一個 handle 歸屬一個 service 時,skynet 框架將對應的網絡消息轉發給它。向一個 handle 發送網絡數據包則不需要當前 service 擁有這個 handle 。

採用前一章節的腳本作爲服務端,測試結果如下:
客戶端:
在這裏插入圖片描述
服務端:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章