M5HttpDown.cpp
资源名称:nettest.rar [点击查看]
上传用户:pmma55
上传日期:2020-12-28
资源大小:17k
文件大小:9k
源码类别:
手机WAP编程
开发平台:
Visual C++
- #include "M5HttpDown.h"
- #include <string.h>
- CM5HttpDown::CM5HttpDown()
- {
- m_sock = (SOCKET)(NULL) ;
- m_running = false ;
- m_is_first_resp = true ;
- m_web_addr = NULL ;
- m_web_fname = NULL ;
- m_custom_callback = NULL ;
- m_custom_data = NULL ;
- m_total_bytes = 0 ;
- m_recv_bytes = 0 ;
- m_recv_buf = new char [HTTP_RECV_BUF_LEN] ;
- memset(m_recv_buf, 0, HTTP_RECV_BUF_LEN) ;
- }
- CM5HttpDown::~CM5HttpDown()
- {
- if(m_recv_buf) delete [] m_recv_buf ;
- if(m_web_addr) delete [] m_web_addr ;
- if(m_web_fname) delete [] m_web_fname ;
- }
- void CM5HttpDown::recv_thread(void * data)
- {
- CM5HttpDown * http_down_ptr = static_cast<CM5HttpDown *>(data) ;
- http_down_ptr->recv_thread_handler() ;
- _endthread() ;
- }
- void CM5HttpDown::recv_thread_handler()
- {
- fd_set recv_fd ;
- struct timeval tmv ;
- int recv_bytes ;
- int jump_length ;
- while(m_running) {
- FD_ZERO(&recv_fd) ;
- FD_CLR(m_sock, &recv_fd) ;
- FD_SET(m_sock, &recv_fd) ;
- tmv.tv_sec = 1 ;
- tmv.tv_usec = 0 ;
- if(select(m_sock+1, &recv_fd, NULL, NULL, &tmv) < 0) {
- #ifdef HTTP_DEBUG_MODE
- printf("select recv failed !n") ;
- fflush(stdout) ;
- #endif
- return ;
- }
- if(FD_ISSET(m_sock, &recv_fd)) {
- // time to read
- recv_bytes = 0 ;
- jump_length = 0 ;
- memset(m_recv_buf, 0, HTTP_RECV_BUF_LEN) ;
- recv_bytes = recv(m_sock, m_recv_buf, HTTP_RECV_BUF_LEN, 0) ;
- if(recv_bytes > 0) {
- if(m_is_first_resp) {
- if(parse_webfile_info(m_recv_buf, &m_total_bytes, &jump_length)) {
- if(m_recv_bytes > 0) m_total_bytes += m_recv_bytes ;
- #ifdef HTTP_DEBUG_MODE
- printf("file length : %dn", m_total_bytes) ;
- #endif
- m_recv_bytes += (recv_bytes - jump_length) ;
- (*m_custom_callback)(m_recv_buf + jump_length,
- recv_bytes - jump_length,
- m_custom_data) ;
- }
- m_is_first_resp = false ;
- continue ;
- } else {
- // common receive procdure
- if((m_recv_bytes + recv_bytes) > m_total_bytes) {
- recv_bytes = m_total_bytes - m_recv_bytes ;
- m_recv_bytes = m_total_bytes ;
- } else {
- m_recv_bytes += recv_bytes ;
- }
- (*m_custom_callback)(m_recv_buf, recv_bytes, m_custom_data) ;
- }
- } else if(recv_bytes == 0) {
- // conn down
- #ifdef HTTP_DEBUG_MODE
- printf("disconn...n") ;
- #endif
- m_running = false ;
- }
- }
- }
- }
- bool CM5HttpDown::send_req(char * req_str, int req_len)
- {
- fd_set send_fd ;
- struct timeval tmv ;
- int send_bytes ;
- if(!m_sock || req_len <= 0 || req_str == NULL) return false ;
- FD_ZERO(&send_fd) ;
- FD_CLR(m_sock, &send_fd) ;
- FD_SET(m_sock, &send_fd) ;
- tmv.tv_sec = 1 ;
- tmv.tv_usec = 0 ;
- if(select(m_sock+1, NULL, &send_fd, NULL, &tmv) < 0) {
- #ifdef HTTP_DEBUG_MODE
- printf("select send failed !n") ;
- fflush(stdout) ;
- #endif
- return false ;
- }
- if(FD_ISSET(m_sock, &send_fd)) {
- send_bytes = send(m_sock, req_str, req_len, 0) ;
- if(req_len != send_bytes) return false ;
- return true ;
- }
- return false ;
- }
- bool CM5HttpDown::parse_uri(char * uri, char * web_addr,
- char * web_fname, int * web_port)
- {
- char * ptr_a = NULL ;
- char * ptr_b = NULL ;
- *web_port = HTTP_WEB_PORT ;
- if(!uri) return false ;
- // search for http or https prefix
- ptr_a = uri ;
- if(!strncmp(ptr_a, HTTP_PREFIX, strlen(HTTP_PREFIX)))
- ptr_a = uri + strlen(HTTP_PREFIX) ;
- else if(!strncmp(ptr_a, HTTPS_PREFIX, strlen(HTTPS_PREFIX)))
- ptr_a = uri + strlen(HTTPS_PREFIX) ;
- // get web_addr without "http://" or "https://" prefix
- ptr_b = strchr(ptr_a, '/');
- if(ptr_b) {
- memcpy(web_addr, ptr_a, strlen(ptr_a) - strlen(ptr_b));
- if(ptr_b + 1) {
- // get web file name
- memcpy(web_fname, ptr_b + 1, strlen(ptr_b) - 1);
- web_fname[strlen(ptr_b) - 1] = ' ' ;
- }
- } else memcpy(web_addr, ptr_a, strlen(ptr_a)) ;
- if(ptr_b) web_addr[strlen(ptr_a) - strlen(ptr_b)] = ' ' ;
- else web_addr[strlen(ptr_a)] = ' ' ;
- // search for uri port number
- ptr_a = strchr(web_addr, ':') ;
- if(ptr_a) *web_port = atoi(ptr_a + 1);
- else *web_port = HTTP_WEB_PORT ;
- return true ;
- }
- bool CM5HttpDown::get_resp_field(char * recv_buf, char * field_name, char * end_flag, char * res)
- {
- char * start_ptr = NULL ;
- char * end_ptr = NULL ;
- start_ptr = strstr(recv_buf, field_name) ;
- if(start_ptr == NULL) return false ;
- start_ptr += strlen(field_name) ;
- end_ptr = strstr(start_ptr, end_flag) ;
- if(end_ptr == NULL) return false ;
- memcpy(res, start_ptr, end_ptr - start_ptr) ;
- res[end_ptr - start_ptr] = ' ' ;
- return true ;
- }
- bool CM5HttpDown::parse_webfile_info(char * recv_buf, int * file_length, int * jump_len)
- {
- char tmp_str[50] ;
- char * offset_str = NULL ;
- #ifdef HTTP_DEBUG_MODE
- printf("%sn", recv_buf) ;
- #endif
- // get file length
- if(!get_resp_field(recv_buf, HTTP_HDR_FILE_LEN, HTTP_HDR_DIV, tmp_str))
- return false ;
- *file_length = atoi(tmp_str) ;
- // get current offset
- offset_str = strstr(recv_buf, HTTP_HDR_END) ;
- if(offset_str == NULL) return false ;
- *jump_len = (int)(offset_str + strlen(HTTP_HDR_END) - recv_buf) ;
- return true ;
- }
- bool CM5HttpDown::init_sock(char * server_name, int server_port)
- {
- struct sockaddr_in sock_in ;
- struct hostent * he ;
- {
- // only worked in dos
- WSADATA wsadata ;
- if (WSAStartup(0x0202, &wsadata) != 0) return false ;
- }
- // get server ip address
- he = gethostbyname(server_name) ;
- if (!he) sock_in.sin_addr.s_addr = inet_addr(server_name) ;
- else {
- sock_in.sin_addr.s_addr = *(unsigned long *)(he->h_addr_list[0]) ;
- #ifdef HTTP_DEBUG_MODE
- printf("ip : %sn", inet_ntoa(sock_in.sin_addr)) ;
- #endif
- }
- sock_in.sin_family = AF_INET;
- sock_in.sin_port = htons(server_port);
- m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
- if(!connect(m_sock,(struct sockaddr *)(&sock_in), sizeof(sock_in))) {
- HANDLE thread_handle ;
- m_running = true ;
- thread_handle = (HANDLE)(_beginthread(CM5HttpDown::recv_thread, 0,(void *)(this))) ;
- return true ;
- }
- return false ;
- }
- bool CM5HttpDown::close_sock()
- {
- if(m_running) {
- m_running = false ;
- Sleep(1000) ;
- if(m_sock) closesocket(m_sock) ;
- }
- {
- // only worked in dos
- WSACleanup() ;
- }
- return true ;
- }
- bool CM5HttpDown::http_down(char * uri,
- RECV_CALLBACK custom_func, void * custom_data,
- int recv_bytes)
- {
- char buffer[HTTP_SEND_BUF_LEN] ;
- memset(buffer, 0, HTTP_TEMP_BUF_LEN) ;
- if(uri == NULL) return false ;
- m_recv_bytes = recv_bytes ;
- m_custom_callback = custom_func ;
- m_custom_data = custom_data ;
- m_web_addr = new char [HTTP_TEMP_BUF_LEN] ;
- m_web_fname = new char [HTTP_TEMP_BUF_LEN] ;
- memset(m_web_addr, 0, HTTP_TEMP_BUF_LEN) ;
- memset(m_web_fname, 0, HTTP_TEMP_BUF_LEN) ;
- parse_uri(uri, m_web_addr, m_web_fname, &m_web_port) ;
- if(m_recv_bytes == 0) {
- snprintf(buffer, HTTP_SEND_BUF_LEN, HTTP_COMMON_GET,
- m_web_fname, m_web_addr, m_web_port) ;
- } else {
- snprintf(buffer, HTTP_SEND_BUF_LEN, HTTP_RESUME_GET,
- m_web_fname, m_web_addr, m_web_port, m_recv_bytes) ;
- }
- #ifdef HTTP_DEBUG_MODE
- printf("%sn", buffer) ;
- #endif
- m_running = true ;
- if(!init_sock(m_web_addr, m_web_port)) return false ;
- // send the request
- return send_req(buffer, strlen(buffer)) ;
- }
- bool CM5HttpDown::http_stop()
- {
- return close_sock() ;
- }