MTK平台socket通信

来源:互联网 发布:人工智能龙头股 编辑:程序博客网 时间:2024/05/27 20:21

1、Data account数据账户

每一个联网的应用都需要设置相关的data account。在建立网络连接时,通过设置的dataaccount id获取联网的配置信息,这个参数决定了用哪个接入点,什么方式进行联网。。data accountid中的信息包括app id, sim id, origin account id, always ask信息。将app id, sim id, original account id, always ask信息encode为account id来创建socket,也就是说对特定的application及data accound id有特定的socket id。

cbm_encode_data_account_id(kal_uint32acct_id, cbm_sim_id_enum sim_id, kal_uint8 app_id, kal_bool always_ask)

 

(1)   app id:对于某个application,需要注册特定的app id,这样在发送或接收数据的时候,就可以根据app_id的不同,来将数据传送给对应的application。用cbm_register_app_id_with_app_info这个API生成。

(2)  Sim id:联网的sim卡信息,也就是现在具体是用哪个sim卡在上网,SIM1值为0,SIM2值为1。

(3)  Origin account id:原始的account id,也就是在数据帐户菜单中对应的apn 的id。

(4)  Always_ask信息:在应用联网之前是否需要弹出一个PopUp,让用户去选择现在联网应用要使用的data account,一般设置为False。

 

kal_bool socket_register_id_get_network_id(void)

{

    cbm_app_info_struct app_info;

    U8 app_id = CBM_INVALID_APP_ID;

    S8 ret = 0;

 

//register app id

    memset(&app_info,0,sizeof(app_info));

    app_info.app_icon_id=0;

    app_info.app_str_id=0;

    app_info.app_type=0;//DTCNT_APPTYPE_NONE;//DTCNT_APPTYPE_EMAIL;

    ret = cbm_register_app_id_with_app_info(&app_info,&app_id);

//get network id

    if (ret != CBM_OK)

        return KAL_FALSE;

    g_gcapp_context.cbm_app_id= app_id;

    sim_id = CBM_SIM_ID_SIM1;

    i = gc_socket_get_acc_prof_id(g_gcapp_apn_param,sim_id);

    cbm_holder_bearer(g_gcapp_context.cbm_app_id);

    g_gcapp_context.nwt_account_id =cbm_encode_data_account_id(i, sim_id, g_gcapp_context.cbm_app_id, KAL_FALSE);

    return KAL_TRUE;

}

4、socket创建及设置完成后,采用TCP方式时,需要跟网络或服务器建立连接,如果返回连接成功,就可以接受或发送数据。

2、soc_create创建socket连接

kal_int8soc_create(kal_uint8  domain,

                    socket_type_enum  type,

                    kal_uint8  protocol,

                    module_type mod_id,

                    kal_uint32 nwk_account_id)

3、soc_setsockopt设置socket非阻塞模式

kal_int8soc_setsockopt(kal_int8 s, kal_uint16 option, kal_uint8 *val, kal_uint8val_size)

创建socket之后,根据需求的不同来设置socket的option。阻塞模式下, 程序在调用接收函数时(如recv),如果没有数据到达, 此函数会一直等待, 即当前线程会被阻塞, 直到有数据时才返回。换句话说,没有数据到达时,程序会在这行代码上等待,不继续往下执行。这样数据未到达时用户界面就会定屏不动,形成假死现象,一般不推荐使用这种模式。

非阻塞模式下, 程序在调用接收函数时, 接收函数会立即返回, 调用方还可以进行其它操作。而当有数据到达时, 操作系统会通过某些方法(如事件)来通知你。也就是说,不论是否有数据到达,程序一直往下执行。而数据到达后,操作系统会通知程序,程序根据操作系统通知的信息来做相应处理。一般推荐设置非阻塞模式。

kal_uint8 val =1;

soc_setsockopt(socket_id,SOC_NBIO,&val,sizeof(val))

4、soc_setsockopt设置Socket选项为异步连接,读,写,关闭

val = SOC_READ |SOC_WRITE | SOC_CLOSE | SOC_CONNECT;

soc_setsockopt(socket_id,SOC_ASYNC,&val,sizeof(val))

5、soc_gethostbyname解析域名

如果是CMNET联网并且请求中用到了英文域名还需要解析域名soc_gethostbyname,除非使用ip作为域名,解析出来的IP作为我们建立连接的目标IP;如果是CMWAP联网,直接跳到第6步,直接连接移动或联通的网关:10.0.0.172:80;

6、soc_connect与服务器建立连接

kal_int8soc_connect(kal_int8 s, sockaddr_struct *addr)

连接操作前要填充服务器IP地址参数addr。若是采用cmnet直连方式,服务器地址是通过域名解析过来的,若采用cmwap代理连接,那么addr的值就是中国移动网关地址10.0.0.172:801。

7、soc_send发送http请求

kal_int32soc_send(kal_int8 s, kal_uint8 *buf, kal_int32 len, kal_uint8 flags)

连上服务器后就可以发送http请求了,其中buf字串需要遵守http连接协议。标准的http请求头如下所示:

GET /XX HTTP/1.1

HOST:XXX (解析出来的IP地址或者中移动网关10.0.0.172)

Connection:Closed

8、soc_recv接收服务器返回的数据

kal_int32 soc_recv(kal_int8s, kal_uint8 *buf, kal_int32 len, kal_uint8 flags)

buf用来保存接收到的字符串,在我们的应用中我们采用全局大数组来保存数据。soc_recv一次接收的数据最好不要过大,最好不要超过2k,一次接收太多数据容易接收不过来。程序中我们可以使用一个循环来接收数据,soc_recv返回的值是接收到的数据字节数,若无数据接收时返回0,这样我们就可以判断数据接收完了。

在实际开发过程中,我们碰到了一个怪异的现象,在断点调试的时候能很好地接收到数据,但是直接运行的时候,往往接收不到数据。猜测可能是数据的时延引起的,就像串口传输数据时的时延一样。所以在这里往往需要将task休眠一会才能接收到数据。但休眠时间的多少不好控制,少了有丢失数据的危险,多了影响响应速度。最后我们的程序未采用循环体接收数据,而是采用递归调用接收数据。这里没想太明白...有想法的朋友可以告知一下。

9、soc_close关闭socket连接

kal_int8soc_close(kal_int8 socket_id)

接收完数据后可以将此Socket连接关闭,socket_id参数是soc_create的返回值。

10、soc_close_nwk_account如果需要,关闭数据账户

至此一个比较完整的Socket连接便介绍完了,当然构建完整的应用还要考虑更多的细节,比如域名解析,出错处理等。

 

http://wenku.baidu.com/link?url=n5CKt7-_F5eQ743aXV13fTdIouAK7BF85L0uPismv362EoqenYoybjXuBzbgNJ8w11Z4Uoi5DBEh76Y0Nr0bKR-57xlZc9Wzb9upImNUmeu

0 0