首先要在mtk上实现socket连接,需要用到以下函数:
1. 创建socket连接
kal_int8 soc_create(kal_uint8 domain,
socket_type_enum type,
kal_uint8 protocol,
module_type mod_id,
kal_uint32 nwk_account_id)
创建socket连接,成功后将返回一个socket_id供以下函数使用.成功运行在手机上的效果是打开黄色边框的GPRS图标,对于手机nwk_account_id的值有10和14分别代表网络接入点cmwap和cmnet由于mtk 只支持cmwap方式故在此我将它设为10.参数说明请参照相关文档。
2. 设置socket非阻塞模式
kal_int8 soc_setsockopt(kal_int8 s, kal_uint16 option, kal_uint8 *val, kal_uint8 val_size)
kal_uint8 val = 1;
soc_setsockopt(socket_id,SOC_NBIO,&val, sizeof(val))
val = SOC_READ | SOC_WRITE | SOC_CLOSE | SOC_CONNECT;
soc_setsockopt(socket_id,SOC_ASYNC,&val,sizeof(val))
3. 连接中国移动网关
kal_int8 soc_connect(kal_int8 s, sockaddr_struct *addr)
手机上网与PC上网不同,手机端需要首先连接移动网关才能进行网络通信,这里需要填充结构体sockaddr_struct的addr及port成员。
4. 发送http请求
kal_int32 soc_send(kal_int8 s, kal_uint8 *buf, kal_int32 len, kal_uint8 flags)
其中buf字串需要遵守http连接协议。
5. 接收数据
kal_int32 soc_recv(kal_int8 s, kal_uint8 *buf, kal_int32 len, kal_uint8 flags)
buf用来保存接收到的字符串,这里需要注意buf的长度不能超过2000,否则上真机的时候一到申请内存空间时就会死机,可以用循环来接收信息。
6. 关闭socket连接
kal_int8 soc_close(kal_int8 s)
参数传入soc_create的返回值。
下面是获取天气预报的代码,这个代码原来是用作获取网络时间的,后来用来做天气预报,所以函数名称不对应,代码浓缩过,如有不懂,可以留言:
unsigned char weather_URL[]={"GET http://61.135.159.21/cgi-bin/weather?0755 HTTP/1.1/r/nHost: 10.0.0.172:80/r/nUser-Agent: */*/r/nAccept:*/*/r/nX-Online-Host: 61.135.159.21/r/nProxy-Connection: Keep-Alive/r/n/r/n"};/*0755 深圳的区号,可以尝试用浏览器打开http://61.135.159.21/cgi-bin/weather?0755,会发生什么呢?*/
/*{"GET http://www.google.com/ig/api?hl=zh_cn&weather=shenzhen HTTP/1.1/r/nHost:www.google.com:80/r/nUser-Agent: */*/r/nAccept:*/*/r/nX-Online-Host:www.weather.com.cn/r/nProxy-Connection: Keep-Alive/r/n/r/n"};这是谷歌的接口,shenzhen是城市*/
static kal_uint8 g_weather_soc_id;
static sockaddr_struct g_weather_ip_addr;
#define SOCKET_BUF_SIZE 1500
void mmi_get_network_time(void)
{
kal_uint8 val;
kal_int8 soc_ret;
#ifndef MMI_ON_HARDWARE_P
soc_init_win32();
#endif
g_weather_soc_id = soc_create(SOC_PF_INET, SOC_SOCK_STREAM, 0, MOD_MMI, 10);
if(g_weather_soc_id<0)
{
weather_display_information((unsigned char *)L"create socket, error!");
return;
}
val = 1;
if(soc_setsockopt(g_weather_soc_id, SOC_NBIO, &val, sizeof(val))<0)
{
weather_display_information((unsigned char *)L"set socket SOC_NBIO error!");
soc_close(g_weather_soc_id);
return;
}
val = SOC_READ|SOC_ASYNC|SOC_CLOSE|SOC_CONNECT;
if(soc_setsockopt(g_weather_soc_id, SOC_ASYNC, &val, sizeof(val))<0)
{
weather_display_information((unsigned char *)L"set socket SOC_ASYNC error!");
soc_close(g_weather_soc_id);
return;
}
memset(&g_weather_ip_addr, 0, sizeof(sockaddr_struct));
g_weather_ip_addr.addr[0] = 10;
g_weather_ip_addr.addr[1] = 0;
g_weather_ip_addr.addr[2] = 0;
g_weather_ip_addr.addr[3] = 172;
g_weather_ip_addr.addr_len = 4;
g_weather_ip_addr.port = 80;
g_weather_ip_addr.sock_type = SOC_SOCK_STREAM;
soc_ret = soc_connect(g_weather_soc_id, &g_weather_ip_addr);
if(soc_ret>=0)
{
get_network_time_socket_send();
return;
}
else if(soc_ret == SOC_WOULDBLOCK)
{
weather_display_information((unsigned char *)L"connect socket, wait...");
SetProtocolEventHandler(get_network_time_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND);
return ;
}
}
void get_network_time_socket_send(void)
{
//unsigned char buf[200];
unsigned char wbuf[400];
kal_int32 ret,len;
/*soc_getsockaddr(g_weather_soc_id, 1, & g_weather_ip_addr);
sprintf((char *)buf, "IP:%d.%d.%d.%d,PORT:%d",
g_weather_ip_addr.addr[0], g_weather_ip_addr.addr[1], g_weather_ip_addr.addr[2],g_weather_ip_addr.addr[3], g_weather_ip_addr.port);
app_asc_str_to_ucs2_str((kal_int8*)wbuf, (kal_int8 *)buf);
weather_display_information(wbuf);如果用另一台手机连接上这个IP,两者之间就可以发送数据,我用J2ME编一个程序放到手机上实现过,不知这里行不行?*/
len = mmi_ucs2_strlen(weather_URL);
ret = soc_send(g_weather_soc_id, weather_URL, len, 0);
mmi_utf8_to_unicode(weather_URL,wbuf);
weather_display_information(wbuf);
if(ret > 0)
{
get_network_time_socket_receive();
}
else
{
SetProtocolEventHandler(get_network_time_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND);
}
}
void get_network_time_socket_receive(void)
{
const unsigned char utf8_head[2]={"|/0"};
const unsigned char href[7]={"href=/"/0"};
unsigned char buf[SOCKET_BUF_SIZE];
unsigned char wbuf[SOCKET_BUF_SIZE*2];
unsigned char *temp_ptr;
int offset;
int soc_ret;
memset(buf, 0, sizeof(buf));
soc_ret = soc_recv(g_weather_soc_id, buf, sizeof(buf), 0);
if(soc_ret > 0)
{
buf[SOCKET_BUF_SIZE-2] = '/0';
buf[SOCKET_BUF_SIZE-1] = '/0';
#if 0
{
unsigned int write_len;
int file_ret;
FS_HANDLE file_handle;
file_handle = FS_Open((WCHAR*)L"C://weather101.txt", FS_CREATE_ALWAYS);
file_ret = FS_Write(file_handle, buf, sizeof(buf), &write_len);
FS_Close(file_handle);
}
#endif
offset=mmi_ucs2_strstr(buf, (unsigned char *)utf8_head);
if(offset>0)
{
temp_ptr = buf;
offset++;
temp_ptr += offset;
offset = mmi_utf8_to_unicode(temp_ptr, g_weather_temperature);
weather_display_information(g_weather_temperature);
soc_close(g_weather_soc_id);
return;
}
offset=mmi_ucs2_strstr(buf, (unsigned char *)href);//the html had move,cennect again
if(offset>0)
{
get_network_time_socket_send();
return;
}
else
{
weather_display_information((unsigned char *)L"received error!wait a minute and try again.");
soc_close(g_weather_soc_id);
return;
}
}
else if(soc_ret == SOC_WOULDBLOCK)
{
SetProtocolEventHandler(get_network_time_socket_notify, MSG_ID_APP_SOC_NOTIFY_IND);
}
}
void get_network_time_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:
get_network_time_socket_receive(); break;
case SOC_WRITE:
get_network_time_socket_send(); break;
case SOC_CONNECT:
get_network_time_socket_send(); break;
case SOC_CLOSE:
break;
default:
break;
}
}