简单设计并开发一个移动通信程序

网络越来越好,手机之间的互动已经是常态,王者荣耀、微信实时视频等,已经将多屏互动推到各到各种应用场景。
为了让大家能清楚地了解多屏互动,我将结合实例对移动设备实时通信进行研究,并系统性地呈现一些解决方案。
最开始,我尝试给大家展示如何建立一个最简单的点对点通信。
万事开头难,先假定一下需求:
局域网内通信。
写一个你看我画的程序。
纯客户端(一开始,我不打算让服务器参与)。

下面对需求进行进一步的分析。

需求分析

我做了一个简单的原型设计,如下图,其实真正的状态比这个稍复杂,这里提供一下 原型链接

需求原型

这里写图片描述

从原型上看,我们的流程应该是下图的形式。

流程图

这里写图片描述

下面我们进行架构设计与开发选型了。

架构设计

基于前文的需求假定进行简单设计网络模型,我将目标的网络分拆成3层:

网络模型

这里写图片描述

对应的开发架构应该是这样的

开发架构

这里写图片描述

开发规则

基于实时通信的高效性,我将底层库的开发语言选择了C++,协议格式选择为二进制,网络层协议选择UDP(后面会有切换TCP的选择)。
通信协议端口我选择12000.

字段注解
底层库开发语言C++
协议格式二进制
网络层协议UDP
通信端口12000

下面我将开始搭建底层库(写到这里还是一行代码都没写,不过现在是国庆节,既然有时间那就开始搞吧)。

底层库搭建

创建工程

工程目录如下
这里写图片描述

我设计的busi头文件,给上层调用的。(详细的见 github)

#ifndef hello_busi_hpp
#define hello_busi_hpp
#include <stdio.h>

namespace hello{

    class BusiInterface{
    public:

        virtual int onInit(int myIp, int myPort);
        virtual int onLink(int srcIndex, int srcIp, int srcPort, const char* srcName, int nameSize);
        virtual int onConfirm(int srcIndex, const char* srcName, int nameSize);
        virtual int onCancel(int srcIndex);
        virtual int onMsg(int srcIndex, const char* msg, int size);




    };

    class Busi{
    public:
        Busi();
        virtual ~Busi();
        virtual int init(BusiInterface* itf);
        virtual int link(const char* myName, int nameSize, int dstIp, int dstPort);
        virtual int confirm(const char* myName, int nameSize, int index);
        virtual int cancel(int index);
        virtual int sendMsg(int index, const char* msg, int size);

    private:

        Busi*                   m_busi;

    };

}
#endif /* hello_busi_h */

花了半天的时间写完了底层库,先来测试一下底层库的连通性,我写了一个程试程序,只列下核心文件, 详细请看github上。

void Test::testBusi()
{
    m_busi = new Busi();
    m_busi->init(this);


    char  ip[128];

    printf("pleast input your name\n");
    fgets(m_name, 127, stdin);


    printf("please input your select\n");
    printf("1 for link\n");
    printf("2 for auto link\n");
    int v;
    scanf("%d", &v);

    if(v == 1){
        printf("please input the dst ip you want link\n");
        scanf("%s", ip);

        int dstIp = inet_addr(ip);

        m_busi->link(m_name, strlen(m_name)+1, dstIp, HELLO_COMM_SERVER_LISTEN_PORT);
    }
    else{
        printf("now you can want link from others\n");
    }

}

void Test::sendMsg(const char *buffer, int size)
{
    m_busi->sendMsg(m_dstIndex, buffer, size);
}


int Test::onInit(int myIp, int myPort)
{
    struct in_addr addr;
    addr.s_addr = myIp;

    printf("on init, my ip:%s, my port:%d\n", inet_ntoa(addr), myPort);

    return HELLO_STATUS_OK;

}
int Test::onLink(int srcIndex, int srcIp, int srcPort, const char* srcName, int nameSize)
{
    struct in_addr addr;
    addr.s_addr = srcIp;

    printf("on link from ip:%s, port:%d, name:%s\n", inet_ntoa(addr),  srcPort, srcName);
    m_busi->confirm(m_name, strlen(m_name), srcIndex);
    printf("now you can send msg to destination\n");
    g_linked = 1;
    m_dstIndex = srcIndex;

    return HELLO_STATUS_OK;
}
int Test::onConfirm(int srcIndex, const char* srcName, int nameSize)
{
    printf("on confirm from index:%d, name:%s\n", srcIndex, srcName);
    m_dstIndex = srcIndex;
    printf("now you can send msg to destination\n");
    g_linked = 1;


    return HELLO_STATUS_OK;
}
int Test::onCancel(int srcIndex)
{
    printf("on cancel from index:%d\n",  srcIndex);
    return HELLO_STATUS_OK;
}
int Test::onMsg(int srcIndex, const char* msg, int size)
{
    printf("on msg from index:%d, msg: size:%d\n", srcIndex, size);
    printf("msg:%s", msg);
    return HELLO_STATUS_OK;
}

因为我有一台mac, 一个ubuntu,所有测试时候,2边都要编译,mac是用xcode比较简单,ubuntu上编写makefile

framework:

BUSI_SRC=$(wildcard busi/*.cpp)
NET_SRC=$(wildcard net/*.cpp)
PACKAGE_SRC=$(wildcard package/*.cpp)
UTIL_SRC=$(wildcard util/*.cpp)

SRC=$(BUSI_SRC) $(NET_SRC) $(PACKAGE_SRC) $(UTIL_SRC)
OBJS=$(patsubst %.cpp, %.o, $(SRC))
CXXFLAGS += -D_WMD -pthread -std=c++11 -g -O0
LDFLAGS += -L/lib64 -pthread
LIB=../lib/libwmd.a 
default: $(LIB)
$(LIB): $(OBJS)
        rm -rf $@
        ar -rs $@ $(OBJS)
clean:
        -rm -rf $(OBJS)
.cpp:
        $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS) $(LIBRARY) $(LIBS)

test


SRC=$(wildcard *.cpp)
OBJS=$(patsubst %.cpp, %.o, $(SRC))
CXXFLAGS += -std=c++11 -g -O0
LDFLAGS += ../lib/libwmd.a -L/lib64 -pthread
APP=./hello.out
default:$(APP)
clean:
        -rm -rf $(OBJS)
        -rm -rf $(APP)
$(APP): $(OBJS)
        $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS)
.cpp:
        $(CXX) -g -o $@ $< $(CXXFLAGS) $(LDFLAGS) $(LIBRARY) $(LIBS)

生成的程序如下:
这里写图片描述

现在我们来实测一下连通性:
我让mac做主动连接的一方,让linux做被动连接。
这里写图片描述

这里写图片描述

然后试着各自问候一下吧
这里写图片描述

这里写图片描述

可以看到2者已经通了,咱们的底层库搭建OK!
感兴趣并助喜欢动手同学,可以 下载代码 实测一下。

写一个你看我画的程序吧

为了方便调试,我选择开发一个mac版的你看我画。

创建工程

在xcode上建立一个spritekit工程
这里写图片描述

这里写图片描述

在storyboard上加入按钮元素并绑定ViewController中的变量。
这里写图片描述

代码目录设计

这里写图片描述

framework为底层库,util为工具目录,adaptor为适配层。

实现绘图功能

创建一个自定义的view用来实现绘画。
这里写图片描述

在实现上我用最简单的绘图API, 不过为了区分对手与我画的,我用了2种颜色。
这里写图片描述

设置自定义鼠标响应事件
这里写图片描述

并在代码里创建1个scene用于加载自定义view.

上下层打通

object c 调用原生C++,我的做法是加一层代理。
我将代码结构设计如下
这里写图片描述

含义

CoreData应用层协议结构
CoreAdaptorobject c 适配
CoreDelegate代码接口
Corec++适配

适配架构

这里写图片描述

在开发的时候,我希望上层在发送消息时,不需要指定IP与端口,而只需要索引就行,因此在framework层
建立一个 地址与索引的对应关系。
这里写图片描述

所以适配层调用接口只需要指定index就行了
这里写图片描述

应用层通信实现

结合之前设计的流程图,这个游戏过程的生命周期用viewcontroller 中的代码表示如下:
这里写图片描述

所以最终连接建立要么在confirm后,要么在onConfirm后。
这里写图片描述

这里写图片描述

start函数其实只是负责切换到画图场景
这里写图片描述

OK,整体代码写完后,我们来演示一下效果。

程序演示

先看下截图
这里写图片描述

没发现markdown能支持视频,所以只能将视频链接发上来:
http://v.youku.com/v_show/id_XMzA4MTQ0NjkzNg==.html?spm=a2h3j.8428770.3416059.1

我画的有点丑,不过没关系,大家可以上github上拉下来自己画。
https://github.com/70207/draw.git

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
课程设计题目:模拟即时通信系统实现 一、题目描述 基于社交的即时通信是腾*公司的主要业务,先后有QQ、微信、微博等服务,可能还将继续推出微商、微唱、微走、微笑等产品。这些软件既可以独立提供服务,又互相辉映关联。腾*公司希望对各系统进行整合形成统一的立体社交软件平台。现请完成该平台的设计并实现。要求如下: 1、用户基本信息: 号码ID,昵称,出生时间,T龄(号码申请时间)、所在地、好友列表、群列表。 微博与QQ共享ID,微信采用独立ID,但是可以与QQ号码绑定对应。其他微X产品也分为这两种情况。 2、好友管理 (1)实现各功能好友信息的添加、修改、删除、查询的功能。 (2)可以查询微X之间各自共同好友。如微信可以添加QQ推荐好友。 3、群管理 (1)设定每个微X功能已有1001、1002、1003、1004、1005、1006等群号。 (2)加入群、退出群、挨T、查询群成员等。 (3)不同微X之间群的理念不同,比如:QQ群可以申请加入,而微信群则只能推荐加入;QQ群允许设置临时讨论组(子群),微信群则不允许;QQ群有以群主为核心的管理员制度而微信群仅有群主为特权账号。 4、开通管理 用户可以选择自己开通该平台的N个微X服务。 5、登录管理 各微X之间只要有一个服务登录,则其它服务简单确认后视为自动登录。 6、功能展示要求(main函数) (1)设计约定。开通服务情况、群成员信息和好友信息可以预先保存到文件中,在系统启动时将这些信息加载到内存中; (2)一个服务登录后,本人开通的其它所有服务均进入开通状态。 (3)服务之间可以依据本人开通的任意另外一个服务的好友添加好友。 (4)展示一个服务当前群的特色功能;在群成员数据不受伤害的前提下,动态变换为其他类型群的管理特色。 (5)实现QQ的点对点的TCP通信的收发功能。(选)提示: a)需要加载ws2_32.lib静态库,打开头文件winsock.h。 b)百度IP地址、端口等概念; c)百度socket编程,关注bind、listen、accept、connect、send、receive等函数用法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值