MTK socket 小结 4

上次说到Demo的socket 链接,先看HTTP请求。

当然要理解这个,得知道一个HTTP请求是什么样子的和HTTP协议的交互过程。要详细了解 可以看 RFC 标准文档。简单来说,HTTP 协议是请求应答模式,客户端发一个请求,服务器短发一个答复。客户端说:要xxx网页,服务器就把xxx网页返回给你。交互就需要一个规范,这个就是请求和应答的头,比如 请求的第一行: GET /index.html HTTP/1.1 就表示要获得 index.html。(如果要在命令行下模拟,可以输入 telnet www.baidu.com 80 , 链接成功后,输入 GET / HTTP/1.1 回车回车,就能获得baidu首页了,这个过程就是模拟了想服务器发送了一个最简单的HTTP 请求)

简单过程分析如下:

1 分析URL 把域名,请求地址,和 端口 拆分开

2 进行域名解析,也就是把网址解析成ip地址,这个是异步的过程

3 等解析完成之后,对这个ip地址进行链接

4 链接成功,组装HTTP 请求 头,发送数据

5 如果发送成功,那么一会就会收到通知,有数据可读

6 收到可读消息后,读取内容。

7 交互完成,关闭socket

具体代码分析:

int en_soc_demo_http_send_request(void) {     // 是否初始化     if (soc_demo_transaction)     {         // 当前状态, HTTP_DNS_QUERY 表示第一步需要域名解析         if (soc_demo_transaction->state == HTTP_DNS_QUERY &&             (soc_demo_app_http_url_struct*) soc_demo_transaction->url_parsed_info == NULL)         {             // 解析URL,主要是把域名,请求地址,端口区分出来             // 比如 http://blog.csdn.net/yanwuxufeng 域名是 http://blog.csdn.net             // 请求地址是yanwuxufeng ,端口默认是 80             soc_demo_transaction->url_parsed_info =                 (soc_demo_app_http_url_struct*) en_soc_demo_http_get_parsed_url(                                                     soc_demo_transaction->url,                                                     soc_demo_transaction->url_len);             if (soc_demo_transaction->url_parsed_info)             {                 // 根据域名,获取域名的ip地址                 // 这是个异步的过程,回调函数得到结果                 (void)en_soc_demo_get_host_by_name(                         HTTP,                         (kal_uint8*) soc_demo_transaction->url_parsed_info->host_name);                 return EN_SOC_SUCCESS;             }             else             {                 en_soc_output_result(EN_SOC_INVAL_PARA, NULL, 0);                 return EN_SOC_INVAL_PARA;             }         }         // 解析完ip地址,就可以封装HTTP 请求头,然后发送         else if (soc_demo_transaction->state == HTTP_TCP_CON_CREATING)         {             kal_int8 ret;              char CRLF[3] = {0x0d, 0x0a, 0x00};             soc_demo_transaction->state = HTTP_TCP_CON_CREATED;             /* Create HTTP Get Message */              // 设置HTTP 请求方法             soc_demo_transaction->snd_data_len = 0;             strcat(soc_demo_transaction->snd_buffer, "GET ");             soc_demo_transaction->snd_data_len += 4;              // 设置请求 URI             if (soc_demo_transaction->url_parsed_info->url_link)             {                 strcat(                     (char*)soc_demo_transaction->snd_buffer,                     (char*)soc_demo_transaction->url_parsed_info->url_link);                 soc_demo_transaction->snd_data_len += soc_demo_transaction->url_parsed_info->url_link_len;                  strcat((char*)soc_demo_transaction->snd_buffer, " ");                 soc_demo_transaction->snd_data_len += 2;             }             else             {                 // 没有就是根目录,                 strcat((char*)soc_demo_transaction->snd_buffer, "/ ");                 soc_demo_transaction->snd_data_len += 2;             }              // 设置协议版本             strcat((char*)soc_demo_transaction->snd_buffer, "HTTP/1.1");             soc_demo_transaction->snd_data_len += 8;                          // 第一行结束,加上 换行符             strcat((char*)soc_demo_transaction->snd_buffer, CRLF);             soc_demo_transaction->snd_data_len += 2;              // 设置主机,在cmwap 请求是,这个是必须的             strcat((char*)soc_demo_transaction->snd_buffer, "Host: ");             soc_demo_transaction->snd_data_len += 6;              //主机域名             strcat((char*)soc_demo_transaction->snd_buffer, (char*)soc_demo_transaction->url_parsed_info->host_name);             soc_demo_transaction->snd_data_len += soc_demo_transaction->url_parsed_info->host_name_len;              strcat((char*)soc_demo_transaction->snd_buffer, CRLF);             soc_demo_transaction->snd_data_len += 2;              strcat((char*)soc_demo_transaction->snd_buffer, "Connection: Closed");             soc_demo_transaction->snd_data_len += 18;              strcat((char*)soc_demo_transaction->snd_buffer, CRLF);             soc_demo_transaction->snd_data_len += 2;              strcat((char*)soc_demo_transaction->snd_buffer, CRLF);             soc_demo_transaction->snd_data_len += 2;              soc_demo_transaction->server_ip_addr.port = soc_demo_transaction->url_parsed_info->ser_port_num;              // 进行链接             ret = soc_connect(soc_demo_transaction->socket_id, &soc_demo_transaction->server_ip_addr);                          // 链接成功,进行下一步动作             if (ret == SOC_SUCCESS)             {                 en_soc_demo_http_send_request();                 return EN_SOC_SUCCESS;             }             // 如果是block,那么进行等待,等到消息的返回             else if (ret == SOC_WOULDBLOCK)             {                 mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND, (PsIntFuncPtr)em_soc_demo_app_socket_notify, MMI_TRUE);                  return EN_SOC_SUCCESS;             }             else             {                 // 错误                 if (ret == SOC_ERROR)                 {                     en_soc_output_result(EN_SOC_PEER_NOT_REACHABLE, NULL, 0);                     return EN_SOC_PEER_NOT_REACHABLE;                 }                 else                 {                     en_soc_output_result(EN_SOC_ERROR, NULL, 0);                     return EN_SOC_ERROR;                 }             }         }         // 链接成功之后,可以发送数据         else if (soc_demo_transaction->state == HTTP_TCP_CON_CREATED || soc_demo_transaction->state == REQ_SEND_RETRY ||                  soc_demo_transaction->state == REQ_SENDING)         {             kal_int32 ret;              // 第一次发送,              if (soc_demo_transaction->state != REQ_SENDING)             {                 soc_demo_transaction->snd_counter = 0;             }             soc_demo_transaction->state = REQ_SENDING;                          // 发送数据             ret = soc_send(                     soc_demo_transaction->socket_id,                     (kal_uint8*) (soc_demo_transaction->snd_buffer + soc_demo_transaction->snd_counter),                     (soc_demo_transaction->snd_data_len - soc_demo_transaction->snd_counter),                     0);                          if (ret > 0)             {                 // 发送完毕                 // 其实这里有个bug                 // 应该是 if ((soc_demo_transaction->snd_counter + ret) == (kal_int32) soc_demo_transaction->snd_data_len)                 // 因为数据量很小,几乎不问题.                  if (ret == (kal_int32) soc_demo_transaction->snd_data_len)                 {                     soc_demo_transaction->state = REQ_SENT;                     soc_demo_transaction->post_retry_counter++;                     em_soc_demo_app_start_timer();  /* wait for servwer's response */                     en_soc_demo_tcp_app_recv_response();                     return EN_SOC_SUCCESS;                 }                 else                 {                     // 发送了一部分,需要继续发送                     soc_demo_transaction->snd_counter += ret;                     return EN_SOC_SUCCESS;                 }             }             else             {                 // bloc 状态,需要等待,直道可以发送                 if (ret == SOC_WOULDBLOCK)                 {                     /* waits for socket notify */                     mmi_frm_set_protocol_event_handler(MSG_ID_APP_SOC_NOTIFY_IND, (PsIntFuncPtr)em_soc_demo_app_socket_notify, MMI_TRUE);                      return EN_SOC_SUCCESS;                 }                 else                 {                     if (ret == SOC_ERROR)                     {                         en_soc_output_result(EN_SOC_PEER_NOT_REACHABLE, NULL, 0);                         return EN_SOC_PEER_NOT_REACHABLE;                     }                     else                     {                         en_soc_output_result(EN_SOC_ERROR, NULL, 0);                         return EN_SOC_ERROR;                     }                 }             }         }         else         {             en_soc_output_result(EN_SOC_ERROR, NULL, 0);             return EN_SOC_ERROR;         }     }     else     {         en_soc_output_result(EN_SOC_ERROR, NULL, 0);         return EN_SOC_ERROR;     } }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值