C 语言-基于 P1300 的 SOCKET 实现

(罗锋 luof520@163.com)

一.怎样使用手机工程模式下 socket

例子
第一步:开通 GPRS 业务
手机拨打 1860 或者发送短信开通 GPRS 套餐。包月 5 元 ,包含 CMWAP 流量 30M/月,如果产生 CMNET 流量,按照 1 元/M 收取。
第二步:设置账号
接入点设置说明:
APN: Access Point Name,接入点名称
连接帐号数值不是绝对的,要根据具体设置决定。
对应的连接帐号在 网络服务 - 帐号资料 - GPRS 里,连接帐号是可以修改的。
根据你程序里使用的id 修改相应的帐号。连接帐号里设置 APN。
10 个连接帐号 id 从 10 开始递增。默认14 是cmwap , 17是cmnet。
JAVA程序使用的网络连接与WAP浏览器设置相同。以中国移动APN为例:
在CMWAP和CMNET下,JAVA程序和WAP浏览器都可以访问互联网络。
不同处如下:

CMWAP访问互联网资源要通过WAP代理服务器;
CMNET可以直接访问互联网服务器;


WAP浏览器网络连接设置在:
1。网络服务 -> WAP -> 设置 -> 编辑设置档 -> “帐号资料”里设置连接帐号;
选择GPRS -> 进行设置,如:CHINA MOBILE GPRS cmwap
“联机型态”里设置代理服务器地址; 选择 HTTP -> 进行设置,如:
  1. 代理服务器:10.0.0.172
  2. 服务器端口:80 或 8080
2。连接帐号设置位置:
网络服务 -> 帐号资料 -> GPRS进入,选择你要设置的一项。
在“GPRS连结点”里设置APN;
    如:把FET GPRS 的APN 由fetnet01 改为cmnet.
如果需要使用自带的WAP浏览器,通过CMNET上网,
除了要把接入点改为cmnet之外,还必须清除代理服务器IP地址。<
设置如下:
在“联机型态”里选择HTTP,“确定”后进入代理服务器编辑界面, 将IP地址都设置为0 。
即:代理服务器:000.000.000.000
        服务器端口:80 或 8080
第三步:进入工程模式
在手机待机界面,点击拨号盘,输入“*#3646633#”,即进入工程模式.
第四步:进行 SOCKET 实验
“Socket Test” 菜单下共有六个选项,使用说明如下:
DNS QUERY----域名解析,输入网址,返回 IP.
举例:输入 www.google.com , 返回 Google 的 IP 地址 72.14.203.104
HTTP GET------输入网址,返回网页信息
举例: 输入 http://www.google.com ,返回
ECHO------------服务器端返回客户端发送的数据。 经过测试,输入后,返回错误,可能服务器端不支持
Date Query-------获取服务器日期时间数据 经过测试,输入后返回错误,可能服务器端不支持
TraceRt---------- 获取路由信息表
例如: 输入 www.google.com,返回数据经过的路由地址和时间
Iperf --------------程序没有实现


二.P1300 socket 编程介绍

1. CMWAP 与 CMNET--

cmwap 和 cmnet 是中国移动 gprs 网络的两个不同的 APN(Access Point Name 接入点名称)。
cmnet 提供 NET 服务,手机使用该服务可以直接访问 internet,获得完全的 internet 访问权,与电脑接入互联网完全一样;
而 cmwap 只能访问 wap 网站,当然也可 以 http 代理协议(80 和 8080 端口)和 wap 网关协议(9201 端口)访问 internet.
总结:cmwap 通过代理路由访问 internet 网,cmnet 直接访问 internet 网!P1300 同时支持 cmwap 和 cmnet 的接入。
注:
2. P1300 socket 接口函数
soc_create---------创建 socket 接口,
其第二个参数表示 Socket 类型,常用的 Socket 类型有两种: 流式 Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。
流式 Socket 是一种面向连接的 Socket,针对于面向连接的 TCP 服务应用; 数据报式 Socket 是一种无连接的 Socket,对应于无连接的 UDP 服务应用。
soc_setsockop----设置 socket option: 非阻塞模式 和 异步 IO 手机平台通讯都是非阻塞模式,因此 soc_connect 和 soc_recv 一般不会马上返 回成功,而是返回 SOC_WOULDBLOCK.意思是要等待一会儿,.所以我们要调用 SetProtocolEventHandler 来设置回调函数处理。
soc_connect---连接指定的 Server,如:代理服务器 10.0.0.172:80。只有面向连接(tcp) 的客户程序使用 socket 时才需要将此 socket 与远端主机相连。无连接协议 (udp)从不建立直接连接。
soc_send------用于面向连接(tcp)的socket方式下数据传输,发送客户端请求
soc_recv------用于面向连接(tcp)的socket方式下数据传输,接收服务器返回信息
soc_sendto----用于无连接(udp)的数据报socket方式下数据传输, 发送客户端请求
soc_recvfrom-用于无连接(udp)的数据报socket方式下数据传输, 接收服务器返回信息
soc_close----关闭 socket 连接

三.TCP 和 UDP 通讯流程

socket 的 udp 方式通讯流程描述
<1>soc_create, 其第二个参数设置为 SOCK_DGRAM
<2>soc_sendto
<3>soc_revfrom
<4>soc_close

socket 的 tcp 方式通讯流程描述
<1>soc_create, 其第二个参数设置为 SOCK_STREAM
<2>soc_connect
<3>soc_send
<4>soc_rev
<5>soc_close

四.P1300 socket 编程实现

目的:通过 CMWAP 和 CMNET 采用 TCP 方式连接 www.google.com
程序说明:

1>使用 CMWAP 连接
static kal_uint32 account_id=14;
kal_uint8 addr[4] = {10, 0, 0, 172};

2>使用 CMNET 连接
static kal_uint32 account_id=17;
kal_uint8 addr[4] = {64, 233, 189, 99};

64, 233, 189, 99 是 www.googel.com 的 ip 地址
3>CMWAP 和 CMNET 采用 TCP 方式连接的区别在于,CMWAP 方式 comnnect 移动网关;CMWAP 方式直接 connect 目标地址
源代码如下:(仅供参考)


#include "PixtelDataTypes.h"
#include "kal_non_specific_general_types.h"
#include "soc_api.h" #include "ProtocolEvents.h" #include "custom_mmi_default_value.h" #include "Unicodexdcl.h" // pfnUnicodeStrcpy #include "NvramType.h" #include "NvramProt.h" #include "DebugInitDef.h" #include "OslMemory.h" #include "Conversions.h" #include "l4c2uem_struct.h" #include "DateTimeGProt.h" #include "Wgui_datetime.h" #include "My_AppDefs.h" #include "Globaldefs.h" #define SOCKET_PACKAGE_HEAD "GET http://www.google.cn HTTP/1.1\r\nHost:www.google.cn\r\nProxy-Connection: Keep-Alive\r\n\r\n" static kal_int8 socket_id=-1; //static kal_uint32 account_id=14;// cmwap 方式连接 static kal_uint32 account_id=17;// cmnet 方式连接 static sockaddr_struct socket_addr; static char rec_tmp[1024]; static int print_x=0; static int rec_print_x = 0; static U8* mmi_Rfid_get_senddata(void); void mmi_Mysocket_exit(void) ; void mmi_Mysocket_recinfo_exit(void) ; static void init_socket(void) ; void socket_receive(void); void socket_send(void); void notify_socket(void *inMsg); extern void soc_init_win32(void); void SSCHandleMySocket(void) { EntryNewScreen(SCR_MY_APP_USER7, mmi_Mysocket_exit, NULL, NULL); entry_full_screen(); clear_screen(); gui_BLT_double_buffer(0, 0, UI_device_width - 1, UI_device_height - 1); SetKeyHandler(GoBackHistory, KEY_RSK, KEY_EVENT_UP); SetKeyHandler(init_socket, KEY_LSK, KEY_EVENT_UP); } static void print_reset() { print_x=0; rec_print_x = 0; } static void print_soc_info(UI_string_type info) { gui_move_text_cursor(0,print_x); gui_set_text_color(UI_COLOR_RED); gui_print_text((UI_string_type)info); gui_BLT_double_buffer(0,0,UI_device_width-1,UI_device_height-1); print_x+=30; } static void print_soc_rec_info(UI_string_type info) { gui_move_text_cursor(0,rec_print_x); gui_set_text_color(UI_COLOR_RED); gui_print_text((UI_string_type)info); gui_BLT_double_buffer(0,0,UI_device_width-1,UI_device_height-1); rec_print_x+=30; } void my_chset_convert(U8*src_data,U8*dest_buff,S32 dest_bufflen) { mmi_chset_convert(MMI_CHSET_GB2312,MMI_CHSET_UCS2, (char*)src_data, (char*)dest_buff, ( kal_int32)(dest_bufflen+1)); } void my_show_rec_info(U8 * recbuff,S32 infolen) { U8* databuff; U8* guiBuffer=NULL; databuff = (U8*)OslMalloc(infolen+1); my_chset_convert(recbuff,databuff,infolen); EntryNewScreen(SCR_MY_APP_USER8,NULL, NULL, NULL); entry_full_screen(); clear_screen(); guiBuffer = GetCurrGuiBuffer(SCR_MY_APP_USER8); ShowCategory74Screen(STR_MY_APP_HELLO, IMG_MY_APP_HELLO, STR_GLOBAL_OK, IMG_GLOBAL_OK, STR_GLOBAL_BACK, IMG_GLOBAL_BACK, databuff, infolen, guiBuffer); OslMfree(databuff); databuff = NULL; SetRightSoftkeyFunction(GoBackHistory, KEY_EVENT_UP); SetLeftSoftkeyFunction(GoBackHistory, KEY_EVENT_UP); gui_BLT_double_buffer(0, 0, UI_device_width - 1, UI_device_height - 1); } void socket_receive(void) { kal_int32 result; U8 data[8]; U8 *databuff; #if 0 kal_int32 strcmpresult; U8* senddata; senddata = mmi_Rfid_get_senddata(); #endif databuff = (U8 *)OslMalloc(8); memset((void*)rec_tmp,0,2048); result=soc_recv(socket_id,(kal_uint8*)rec_tmp,2048,0); if(result>0) { print_soc_info(L"--rev OK!"); my_show_rec_info((U8 *)rec_tmp,result); #if 0 strcmpresult = strcmp(senddata,rec_tmp); /*判断发送数据是否完整*/ if(!strcmpresult) { clear_screen(); init_socket(); } #endif return; } else if(result==0) { print_soc_info(L"--rev result==0!"); SetProtocolEventHandler(notify_socket, MSG_ID_APP_SOC_NOTIFY_IND); return; } else if(result==SOC_WOULDBLOCK) { print_soc_info(L"--rev SOC_WOULDBLOCK!"); SetProtocolEventHandler(notify_socket, MSG_ID_APP_SOC_NOTIFY_IND); return; } else { print_soc_info(L"--rev error!"); result = -result; sprintf((char*)data,"-%02d\0",result); mmi_chset_convert(MMI_CHSET_GB2312,MMI_CHSET_UCS2, (char*)data,(char*)databuff, (kal_int32)(8)); print_soc_info((UI_string_type)databuff); OslMfree(databuff); databuff = NULL; soc_close(socket_id); return; } } void socket_send(void) { kal_int32 result; U8 data[8]; U8 *databuff; databuff = (U8 *)OslMalloc(8); /*SOCKET_PACKAGE_HEAD请求获得一个网页 * 如果要上传数据只需把你的数据发送到你连接的服务器 */ result=soc_send(socket_id,(kal_uint8*)SOCKET_PACKAGE_HEAD,strlen(SOCKET_PACKAGE_HEAD),0); if(result>0) { print_soc_info(L"--send OK!"); socket_receive(); return; } else { if(result==SOC_WOULDBLOCK) { print_soc_info(L"--send SOC_WOULDBLOCK!"); SetProtocolEventHandler(notify_socket, MSG_ID_APP_SOC_NOTIFY_IND); return; } else { if(result==SOC_ERROR) { print_soc_info(L"--send error!"); soc_close(socket_id); return; } else { print_soc_info(L"--send other error!"); result = -result; sprintf((char*)data,"-%02d\0",result); mmi_chset_convert(MMI_CHSET_GB2312,MMI_CHSET_UCS2, (char*)data,(char*)databuff, (kal_int32)(8)); print_soc_info((UI_string_type)databuff); OslMfree(databuff); databuff = NULL; soc_close(socket_id); return; } } } } void notify_socket(void *inMsg) { app_soc_notify_ind_struct *soc_notify; soc_notify=(app_soc_notify_ind_struct *)inMsg; print_soc_info(L"Notify Soket!"); if(soc_notify->socket_id!=socket_id) { print_soc_info(L"---Notify NO Socket!"); return; } switch(soc_notify->event_type) { case SOC_WRITE: print_soc_info(L"---Notify Socket Write!"); break; case SOC_READ: print_soc_info(L"---Notify Socket Read!"); socket_receive(); break; case SOC_CONNECT: print_soc_info(L"--Notify Soket Connect!"); socket_send(); break; case SOC_CLOSE: print_soc_info(L"---Notify Soket Close!"); soc_close(socket_id); break; default: print_soc_info(L"---Noticfy Scket Error!"); soc_close(socket_id); socket_id=-1; break; } } static void init_socket(void) { kal_int8 ret; kal_uint8 val=1; print_reset(); print_soc_info(L"Start Soket Create!"); socket_id=soc_create(PF_INET,SOCK_STREAM,0,MOD_MMI,account_id);//新建连接 if(socket_id<0) { print_soc_info(L"Socket Create Error!"); return; } else { if(soc_setsockopt(socket_id,SOC_NBIO,&val,sizeof(val))<0)//设置 socket 非阻塞模式 { print_soc_info(L"Set socket to nonblock mode error!"); return; } val=SOC_READ|SOC_WRITE|SOC_CLOSE|SOC_CONNECT; if(soc_setsockopt(socket_id,SOC_ASYNC,&val,sizeof(val))<0)//设置异步 I/O { print_soc_info(L"Set socket to nonblock mode error!"); return; } } print_soc_info(L"Start Socket Created Connect!"); //kal_uint8 addr[4] = {10, 0, 0, 172}; //cmwap 方式连接 //kal_uint8 addr[4] = {72, 14, 203, 104};//www.googel.com cmnet 方式连接 socket_addr.addr_len=4; socket_addr.port=80; #if 0 socket_addr.addr[0]=10; socket_addr.addr[1]=0; socket_addr.addr[2]=0; socket_addr.addr[3]=172; #endif /*ip地址应该是你要传数据的服务器的地址 在这里我使用的是谷歌的*/ #if 1 socket_addr.addr[0]=72; socket_addr.addr[1]=14; socket_addr.addr[2]=203; socket_addr.addr[3]=104; #endif ret=soc_connect(socket_id,&socket_addr); if(ret==SOC_SUCCESS) { print_soc_info(L"connect SOC_SUCCESS!"); socket_send(); } else if(ret==SOC_WOULDBLOCK) { print_soc_info(L"connect SOC_WOULDBLOCK!"); SetProtocolEventHandler(notify_socket, MSG_ID_APP_SOC_NOTIFY_IND); return; } else { if(ret==SOC_ERROR) { print_soc_info(L"connect SOC_ERROR!!"); soc_close(socket_id); return; } print_soc_info(L"connect OTHER_ERROR!!"); soc_close(socket_id); return; } } static void exit_socket() { soc_close(socket_id); print_soc_info(L"Start Socket Close!"); } void mmi_Mysocket_exit(void) { history currHistory; S16 nHistory = 0; currHistory.scrnID = SCR_MY_APP_USER7; currHistory.entryFuncPtr = SSCHandleMySocket; pfnUnicodeStrcpy( (S8*)currHistory.inputBuffer, (S8*)&nHistory); AddHistory(currHistory); exit_socket(); } static U8* mmi_Rfid_get_senddata(void) { MYTIME init_time; U8 datetime[19]; //上传数据时系统时间 U8 busNum[6] = "12345"; //可以是sim卡号 S32 collectData = 6666; // 交易总金额/*在这里只是调试用数据*/ U8 data[30]; GetDateTime(&init_time); sprintf((char *)datetime, "%04d-%02d-%02d %02d:%02d:%02d\0", init_time.nYear,init_time.nMonth, init_time.nDay,init_time.nHour,init_time.nMin, init_time.nSec); sprintf((char*)data,"%s:%s:%04d",datetime,busNum,collectData); return data; }

302 Found

302 Found


nginx/1.8.0