zoukankan      html  css  js  c++  java
  • 使用UDP完成网络通信

    语言聊天有可以接受丢包但是不能接受乱序的特性,所以可以采用UDP来

    传输数据提高效率。

        因为UDP本身不可靠传输的特性,为了保证玩家可靠的接入服务器和一些

    操作的正确执行,还是需要一些额外的代码保证UDP的可靠性传输。

        一个简单的方案是在发送端发送一个包之后,等待接收端发送的recvack,

    如果没有接收到recvack则重复发送直到超时。发送端接到recvack则发送

    confrimack。接收端若没有收到confrimack重复发送知道超时。

        为了区分可靠和非可靠性传输,为以枚举的形式封包提供了不同的包类型

    需要提供不同的:

    enum sendtype{

        safe_send,

        unsafe_send,

    并且提供不同的发送接口:

    void unsafe_send(char* buf,int len,const sockaddr* addr, int addrlen){

        int datalen += sizeofsenddatahead;

        senddata * data = (senddata*)malloc(datalen);

        data->type = unsafe_send;

        data->len = len;

        memcpy(data->data, buf, len);

        sendto(fd, data, datalan, 0, addr, addrlen);

    }

    void safe_send(char* buf,int len,const sockaddr* addr,int addrlen){

        int datalen += sizeofsenddatahead;

        senddata * data = (senddata*)malloc(datalen);

        data->type = safe_send;

    接收端在接收到数据后,如果是safe_send,则发送recvack:

    void sendrecvack(sockaddr_in & addr, int addrlen){
      recvack cmd;
      cmd.isrecv = cmdrecvack;
      safe_send(&cmd, sizeofconfrimack, (sockaddr*)&addr, addrlen);

    发送端在接收到recvack后,发送confrimack:

    void sendconfrimack(sockaddr_in & addr, int addrlen){

        confrimack cmd;

        cmd.isrecv = cmdconfrimack;

        unsafe_send(&cmd, sizeofconfrimack, (sockaddr*)&addr, addrlen);

    使用心跳控制重发包:

    void safesendheadbeat(int time, void * data){

        if (!vsenddata.empty()){

            senddata * data = vsenddata.front();

            sendto(fd, data, data->len, 0, addr, addrlen);

        }

        addtime(25,  safesendheadbeat, data);

    使用心跳控制recvack:

    void recvackheadbeat(int time, void * data){

        if (recvack != 0){

            sendto(fd, recvack, recvack->len, 0, addr, addrlen);

        }

        addtime(25,  recvackheadbeat, recvack);

  • 相关阅读:
    指定的 LINQ 表达式包含对与不同上下文关联的查询的引用
    无法为具有固定名称“System.Data.SqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类
    获取路径 GetModuleFileName() GetModuleFileName() GetCurrentDirectory
    重启动界面 ShellExecute() ShellExecute()
    MFC 强大功能函数
    extern 头文件 定义&声明
    全局变量/常量
    有时不需要头文件包含也能编译过
    字符串(3):字符串与函数
    函数不能传递动态内存
  • 原文地址:https://www.cnblogs.com/qianqians/p/4186338.html
Copyright © 2011-2022 走看看