当前位置:文档之家› 网络通信流程

网络通信流程

MTK 网络通信详解先这里说一下MTK 的通信流程,一些新人还是对这个不熟悉的。

其实这个和PC 机的通信差不多,大同小异。

PC 机上是直接send 发送数据的,而MTK 是发送数据时要加一个HTTP 头再发送出去,这就是传说中的CMWAP 模式通信,与CMWAP 并列的是CMNET 通信,这里先不详讲CMWAM 与CMNET 了,后面弄个专题。

这张流程图,CSDN不知道怎么回事不能上传呆会给个URL下面来详细介绍下这些函数及注意事项kal_int8 soc_create(kal_uint8 domain,socket_type_enum type,kal_uint8 protocol,module_type mod_id,kal_uint32 nwk_account_id);比如1)kal_uint32 nwk_account_id = 10;soc_create(PF_INET, SOCK_STREAM, 0, MOD_MMI, nwt_acount_id);这里关键是nwt_acount_id 这个值,很多MTKer 都不知道这个值该填什么,一般情况下填10 ,因为10 在MTK 手机里设置的10 代表着中国移动,如果是CMNET 通信的话就就填14 了,如今的MTK 手机都已经很牛X 了,支持双卡双待。

这时又得说明当前是通信是想有卡 1 还是卡 2 去通信,因为不同的卡nwt_acount_id 又不一样,所以在soc_create 之前得区分当前卡是卡1 还是卡2 。

2) kal_int8 soc_setsockopt(kal_int8 s,kal_uint32 option,void *val,kal_uint8 val_size);3)U32 val1 = SOC_READ | SOC_WRITE | SOC_CLOSE | SOC_CONNECT;soc_setsockopt(socketid, SOC_ASYNC, &val1, sizeof(val));把socketid 的设置成异步,选项有SOC_READ ,SOC_WRITE ,SOC_CLOSE ,SOC_CONNECT 。

4)U32 val = 1;soc_setsockopt(socketid, SOC_NBIO, &val, sizeof(val));把socketid 设置成非阻塞5)setProtocolEventHandler(soc_app_socket_notify,MSG_ID_APP_SOC_NOTIFY_IND);设置消息的触发消息响应函数,当有val1 的类型的触发消息时会自动调用soc_app_socket_notify 这个函数。

6) kal_int8 soc_connect(kal_int8 s, sockaddr_struct *addr);typedef struct{socket_type_enum sock_type;kal_int16 addr_len;kal_uint16 port;/* For keep the 4-byte boundary *//* please do not declare other variables above addr */kal_uint8 addr[MAX_SOCK_ADDR_LEN];} sockaddr_struct;CMWAP 通信时, 手机端需要首先连接移动网关才能进行网络通信, 这里需要填充结构体sockaddr_struct 的addr 及port 成员,sockaddr_struct sockaddr = {0};sockaddr.addr[0] = 10;sockaddr.addr[0] = 0;sockaddr.addr[0] = 0;sockaddr.addr[0] = 172;sockaddr.addr_len = 4sockaddr.port = 80;如果是CMNET 通信时就IP 及端口填自己要访问的服务器IP{byte1, byte2, byte3, byte4} 及地址server_portsockaddr_struct sockaddr = {0};sockaddr.addr[0] = byte1;sockaddr.addr[1] = byte2;sockaddr.addr[2] = byte3;sockaddr.addr[3] = byte4;sockaddr.addr_len = 4sockaddr.port = server_port;到这里连接请求已经发送出去了。

接着会有服务器发一个连接响应,也就是通知我服务器已经接到你客户端的连接请求,这里在客户端也就会触发我们先前设置的SOC_CONNECT 消息,并由soc_app_socket_notify 来响应这个事件.这是原型void soc_app_socket_notify(void *inMsg);而inMsg 指向的是app_soc_notify_ind_struct 这么一个结构体typedef struct{kal_uint8 ref_count;kal_uint16 msg_len;kal_int8 socket_id; /* socket ID */soc_event_enum event_type; /* soc_event_enum */kal_bool result;soc_error_enum error_cause; /* used only when EVENT is close/connect */ kal_int32 detail_cause; /* refer to ps_cause_enum if error_cause is* SOC_BEARER_FAIL */} app_soc_notify_ind_struct;/* event */typedef enum{SOC_READ = 0x01, /* Notify for read */SOC_WRITE = 0x02, /* Notify for write */SOC_ACCEPT = 0x04, /* Notify for accept */SOC_CONNECT = 0x08, /* Notify for connect */SOC_CLOSE = 0x10 /* Notify for close */} soc_event_enum;/* Socket return codes, negative values stand for errors */typedef enum{SOC_SUCCESS = 0,SOC_ERROR = -1,SOC_WOULDBLOCK = -2,SOC_LIMIT_RESOURCE = -3, /* limited resource */SOC_INV ALID_SOCKET = -4, /* invalid socket */SOC_INV ALID_ACCOUNT = -5, /* invalid account id */SOC_NAMETOOLONG = -6, /* address too long */SOC_ALREADY= -7, /* operation already in progress */SOC_OPNOTSUPP = -8, /* operation not support */SOC_CONNABORTED = -9, /* Software caused connection abort */ SOC_INV AL = -10, /* invalid argument */SOC_PIPE = -11, /* broken pipe */SOC_NOTCONN = -12, /* socket is not connected */SOC_MSGSIZE = -13, /* msg is too long */SOC_BEARER_FAIL = -14, /* bearer is broken */SOC_CONNRESET = -15, /* TCP half-write close, i.e., FINED */ SOC_DHCP_ERROR = -16,SOC_IP_CHANGED = -17,SOC_ADDRINUSE = -18,SOC_CANCEL_ACT_BEARER = -19 /* cancel the activation of bearer */} soc_error_enum;在这里app_soc_notify_ind_struct 里会经常捕捉到错误的SOC_CONNECT 消息,这时app_soc_notify_ind_struct 里的result 为KAL_FALSE, soc_error_enum 为-14 (SOC_BEARER_FAIL ),表示建立连接失败。

分析了原因,有以下几个原因,一、soc_create 时的nwk_conunt_id 弄错了,二、soc_connect 的IP和端口弄错了,三、手机卡,没话费了,四、手机卡没有开通GPRS 。

7) 发送数据仅有当SOC_CONNECT 消息正常触发,且拥有正确的值时就可以直接soc_send 了kal_int32 soc_send(kal_int8 s,kal_uint8 *buf,kal_int32 len,kal_uint8 flags)egS32 ret = 0;char buf[1024*20] = {0};http_get_buf(buf);ret = soc_send(socketid, buf, strlen(buf), 0);8) 如果发送成功的话,这里有一个SOC_RECV 三番五次来造访我们的soc_app_socket_notify 函数,我们也别客气。

开始接收数据kal_int32 soc_recv(kal_int8 s,kal_uint8 *buf,kal_int32 len,kal_uint8 flags)egS32 ret = 0;char buf[1024*20] = {0};ret = soc_recv(socketid, buf, 1024*20, 0);9) 最后接收完了就可以关闭socket 了soc_close(socketid);MTK平台下使用socket实现http通讯收藏2010-03-06 03:191.移动代理服务器IP:10.0.0.172 port:802.MTK socket接口1)soc_create创建socket接口2)soc_setsockopt设置socket option3)soc_connect建立连接,在这里连接的对像是代理服务器10.0.0.1724)soc_send发送信息5)soc_recv接收信息6)非阻塞模式,手机平台通讯都是非阻塞模式,因此soc_connect和soc_recv一般不会马上返回成功,而是返回SOC_WOULDBLOCK.意思是要等待一会儿,.所以我们要调用SetProtocolEventHandler来设置回调函数.3.http格式一个的HTTP请求格式如下:GET HTTP/1.1\r\nHost: \r\nProxy-Connection: Keep-Alive\r\n\r\nGET后面是请求的文件,Host后面是请求的域名.每行都以\r\n结束.最后还必须有一个空行.一般情况下请求包只有包头,没有包体.一个的HTTP响应消息格式如下:HTTP/1.1 200 OK [ZTEOSE]\r\nServer: ZTEOSE\r\nDate: Tue, 15 Jul 2008 04:50:08 GMT\r\nServer: WebLogic Server 8.1 SP3 Tue Jun 29 23:11:19 PDT 2004 404973 with CRs:\r\nSet-Cookie: jid=L8sQcQ71W0!225012077; path=/\r\nContent-Length: 494\r\nContent-Type: text/vnd.wap.wml;charset=UTF-8\r\n\r\n(数据....)通常,移动响应的第一个包是重定向,如下所示:<?xml version="1.0"?><!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN""/DTD/wml_1.1.xml"><wml><head><meta http-equiv="Cache-Control" content="max-age=0" forua="true"/> <meta http-equiv="Cache-Control" content="no-cache" forua="true"/><meta http-equiv="Cache-Control" content="must-revalidate"forua="true"/></head><card id="card" title="" ><onevent type="onenterforward"><go href=":80/?t=08458"></go></onevent></card></wml>其中:80/?t=08458就是要重定向的URL,客户端接到这个包之后要重新发一个请求包,而且把GET HTTP/1.1\r\n改成:GET :80/?t=08458 HTTP/1.1\r\n之后就能得到想要的数据了.//#define URL0 "POST / HTTP/1.1\\r\\nX-Online-Host::80\\r\\nKeep-Alive:c lose\\r\\nContent-Lengt h:3\\r\\n\\r\\nabc"//#define URL0 "POST /mvc HTTP/1.0\\r\\nAccept: text/xml, application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*\\r\\nAccept-Language:z h-tw,en-us,en\\r\\nAccept-Encoding:gzip, deflate\\r\\nUser-Agent: Mozilla/4.0\\r\\nContent-Type:application/x-www-form-urlencoded\\r\\nHost:222.66.42.154:80Co ntent-Length:404\\r\\nKeep-Alive:300\\r\\nConnection:Keep-Alive\\r\\n\\r\\nServ_ID=S0001&V er =1.0&Tx_ID=T0003&Receiver=138********"//#define URL1 "GET \\r\\nProxy-Connection: Keep-Alive\\r\\n\\r\\n>HTTP/1.1\\r\\nHost:\\r\\nProxy-Connection: Keep-Alive\\r\\n\\r\\n"#define URL "GET /lenovo/data/mobile/test_zlib/contents.meta HTTP/1.1\\\\nX-ONLINE-HOST:221.223.53.34:80\\\\n\\\\r\\\\n"static kal_int8 soc_id;void my_socket_receive(void);void my_socket_notify(void *msg_ptr);void my_socket_send(void){kal_int32 ret;ret = soc_send(soc_id, (unsigned char*)URL, strlen(URL), 0);//kal_prompt_trace(MOD_TCPIP," <<<<<<<- %d >>>>>>>>", strlen(URL));if( ret > 0){my_socket_receive();}else{SetProtocolEventHandler(my_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND);}}#define BUF_SIZE 200void my_socket_receive(void){kal_uint8 rbuf[BUF_SIZE];int ret;unsigned short wBuf[BUF_SIZE+1];ret = soc_recv( soc_id, rbuf, BUF_SIZE, 0);if( ret > 0){int i;//kal_prompt_trace(MOD_TCPIP," <<<<<<<- %d >>>>>>>>", rbuf);if( ret == SOC_WOULDBLOCK){SetProtocolEventHandler(my_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND);}}}void my_socket_notify(void *msg_ptr){app_soc_notify_ind_struct *soc_notify = (app_soc_notify_ind_struct *)msg_ptr;switch(soc_notify->event_type){case SOC_READ:my_socket_receive();break;case SOC_WRITE:my_socket_send();break;case SOC_CONNECT://kal_prompt_trace(MOD_TCPIP," <<<<<<<<<>>>>>>>");my_socket_send();break;case SOC_CLOSE:break;default:break;}}int my_test_socket_entry(){kal_uint8 val=KAL_TRUE;kal_int8 soc_ret;//kal_int8 soc_id;soc_id = soc_create(PF_INET, SOCK_STREAM, 0, MOD_MMI, 14); //14); //TPC_ACCOUNT_ID);if( soc_id < 0)return 0;if(soc_setsockopt(soc_id, SOC_NBIO, &val, sizeof(val)) <0){return 0;}val=SOC_READ | SOC_WRITE | SOC_CLOSE | SOC_CONNECT;if(soc_setsockopt(soc_id, SOC_ASYNC, &val, sizeof(val)) <0){return 0;}memset( &my_ip_addr, 0, sizeof(sockaddr_struct));my_ip_addr.addr[0] = 10; //10;my_ip_addr.addr[1] = 0; //0;my_ip_addr.addr[2] = 0; //0;my_ip_addr.addr[3] = 172; //172;my_ip_addr.addr_len = 4;my_ip_addr.port = 80;my_ip_addr.sock_type = SOCK_STREAM;soc_ret = soc_connect(soc_id, &my_ip_addr);if( soc_ret >= 0){my_socket_send();return soc_ret;}else if( soc_ret == SOC_WOULDBLOCK) /* 一般此条件都会成立,返回! */{//Jx_debug("SOC_WOULDBLOCK!!!\\r\\n");SetProtocolEventHandler(my_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND); return soc_ret;}return 1;}#endif本文来自:我爱研发网() - R&D大本营详细出处:/Blog/Archive_Thread.asp?SID=20581MTK平台用Socket实现HTTP请求一、MTK平台Socket联网过程熟悉PC机编程的人都知道,Socket编程接口分两套:TCP和UDP;TCP和UDP中又有服务器端和客户端的概念,这里讲的是TCP的客户端编程接口。

相关主题