Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 3 của 3
  1. #1
    Ngày tham gia
    Dec 2015
    Bài viết
    0

    Nhận dữ liệu hàm WSAWaitForMultipleEvents bi time out !

    Sau một thời gian ngồi loay hoay cũng mò mẫm ra một số vấn đề về socket trong win !
    Do trình em gà quá ...có nhiều chỗ khó hiểu . Hôm nay lại mạo muội post bài nhờ các bác giúp đỡ em chút . Thời gian đã gấp gáp vì có mỗi doạn code mà gần 1 tháng không thông hết !

    Đoạn code của em gửi requets tới một máy chủ web chờ đợi và nhận về là dữ liệu dạng html . Em dùng hàm WSAWaitForMultipleEvents để thông báo sự kiện FD_CONNECT , FD_WRITE , FD_READ

    Tất cả mọi việc diễn ra bình thường nếu như em ko gặp chút trở ngại trong việc giải quyết vấn đề cuối cùng . Như các bác đã biết trong một trình duyệt ví dụ như IE hay Firefox luôn luôn biết khi nào đã nhận dữ liệu xong ......kể cả khi dữ liệu nhận về chỉ là một file txt hay một file ảnh mà ko có chút mã html nào cả !

    Mã:
    #include "stdafx.h"#ifndef UNICODE#define UNICODE#endif #define WIN32_LEAN_AND_MEAN#include <iostream>#include <stdio.h>#include <winsock2.h>#include <fstream>#pragma comment (lib,"ws2_32.lib")using namespace std; #define DEFAULT_BUFLEN 1025#define DEFAULT_PORT 80void send_http(SOCKET ConnectSocket){    char * get = "GET / HTTP/1.1
    ";    char * hots = "Host: dantri.com.vn
    ";    char *use_agen = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110420 Firefox/3.6.17
    ";    char *st = "Connection: Keep-Alive
    ";    char * acc_encoding ="Accept-Encoding: gzip
    ";    char * acc_languege = "Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7
    ";    char *cache = "Cache-Control: no-cache
    ";    char  *relink = "Referer: http://google.com/
    
    ";    // gui ...du lieu                                                                                 send( ConnectSocket, get, (int)strlen(get), 0 );                                                                                send( ConnectSocket, hots, (int)strlen(hots), 0 );                                                                                send( ConnectSocket, acc_encoding, (int)strlen(acc_encoding), 0 );                                                                                send( ConnectSocket, acc_languege, (int)strlen(acc_languege), 0 );                                                                                send( ConnectSocket, cache, (int)strlen(cache), 0 );                                                                                send( ConnectSocket, st, (int)strlen(st), 0 );                                                                                send( ConnectSocket, use_agen, (int)strlen(use_agen), 0 );                                                                                send( ConnectSocket, relink, (int)strlen(relink), 0 );   } /////////////////////////////////////////////////////////////////int main() { // Khai báo kh?i t?o socket    int iResult;    WSADATA wsaData;    hostent *ConnectPC=NULL;    fstream file;    struct sockaddr_in clientService;     size_t new_size;    SOCKET ConnectSocket;    char recvbuf[DEFAULT_BUFLEN] = {0};    WSAPROTOCOL_INFO *lpProtocolBuf = NULL;    DWORD dwErr,dwBufLen = 0;    // Khai báo thông s? cho s? lý s? ki?n    DWORD event_total=0;    DWORD index;    WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS],new_event;    WSANETWORKEVENTS NetworkEvents;     //----------------------     iResult = WSAStartup(MAKEWORD(2,2), &wsaData);    if (iResult != NO_ERROR) {        wprintf(L"WSAStartup failed with error: %d
    ", iResult);          }    // ===============bo dem ======================          int nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);          if(nRet != SOCKET_ERROR){                      cout<<"goi lan 1
    ";          }          else if((dwErr = WSAGetLastError()) != WSAENOBUFS){               cout<<"WSAEnumProtocols() failed with code %d
    "<<WSAGetLastError();          }          else{              cout<<"is ok
    ";              lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);              if (lpProtocolBuf)              {                  nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);                  if (nRet == SOCKET_ERROR)                  {                      printf("WSAEnumProtocols() failed with code %d
    ", WSAGetLastError());                  }                  else                  {                      cout<<"rat ok
    ";                  }              }          }     ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if (ConnectSocket == INVALID_SOCKET) {        wprintf(L"socket failed with error: %ld
    ", WSAGetLastError());        WSACleanup();        return 1;    }    char * domain ="dantri.com.vn";              ConnectPC = gethostbyname(domain);    clientService.sin_family = AF_INET;    clientService.sin_addr.s_addr = (*(DWORD*)ConnectPC->h_addr_list[0]);    clientService.sin_port = htons( DEFAULT_PORT );     iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );    if (iResult == SOCKET_ERROR) {        wprintf(L"connect failed with error: %d
    ", WSAGetLastError() );        closesocket(ConnectSocket);        WSACleanup();        return 1;  }    ///////////////////////////////     EventArray[event_total] = WSACreateEvent();    WSAEventSelect(ConnectSocket,EventArray[event_total],FD_CONNECT | FD_WRITE | FD_READ);    event_total++;    index = WSAWaitForMultipleEvents(event_total, EventArray, FALSE, WSA_INFINITE, FALSE); // tr? v? t?ng s? các s? ki?n .....           WSAEnumNetworkEvents(ConnectSocket,EventArray[index - WSA_WAIT_EVENT_0],&NetworkEvents);     cout<<"kukuchima
    ";             if(NetworkEvents.lNetworkEvents & FD_CONNECT)        {            if (NetworkEvents.iErrorCode[FD_CONNECT_BIT] == 0){                cout<<"xuat hien mot yeu cau ket noi .... 
    ";                send_http(ConnectSocket);             }            else{                cout<<"Loi su kien connect ! ma loi ..."<<WSAGetLastError()<<endl;            }        }                       //======================================         if(NetworkEvents.lNetworkEvents & FD_WRITE)        {            if(NetworkEvents.iErrorCode[FD_WRITE_BIT] == 0)            {                cout<<" Dang gui Request toi sever .....
    ";                index = WSAWaitForMultipleEvents(event_total, EventArray, FALSE, 5000, FALSE);                WSAEnumNetworkEvents(ConnectSocket,EventArray[index - WSA_WAIT_EVENT_0],&NetworkEvents);            }            else{                cout<<"Loi su kien gui ......"<<WSAGetLastError()<<endl;            }        }        //esle{cout<<"Chua "<<endl;}                     //===============================================        if(NetworkEvents.lNetworkEvents & FD_READ)        {         if(NetworkEvents.iErrorCode[FD_READ_BIT] == 0)            {                cout<<" Du lieu gui ve thanh cong . Da san sang de doc o bo dem .....
    ";//<<WSAGetLastError()<<endl;                 int sl =0;                int iRes=0;                 do{                                                                                                                 iRes = recv(ConnectSocket, recvbuf, sizeof(recvbuf)-1, 0);                                                                                                                          sl = sl+1;                                        //cout<<sl<<endl;                                              cout<<"
     so byet nhan"<<iRes<<" --lan nhan thu"<<sl<<"------
    ";                                        if(iRes < 0)                                        {                                                                                       cout<<"da nhan xong du lieu 
    ";                                        break;                                        }                                        else{                                                                                    }               // goi lai ham WSAWaitForMultipleEvents                                                        index = WSAWaitForMultipleEvents(event_total, EventArray, FALSE, 5000, FALSE);                                                        WSAEnumNetworkEvents(ConnectSocket,EventArray[index - WSA_WAIT_EVENT_0],&NetworkEvents);                                        // cong viec su ly du lieu ....neu co                                         recvbuf[iRes]=0;                                                          }while(iRes>0);            }            else            {                cout<<"Loi su kien doc du lieu .....
    ";            }        }       iResult = closesocket(ConnectSocket);    if (iResult == SOCKET_ERROR) {        wprintf(L"close failed with error: %d
    ", WSAGetLastError());        WSACleanup();        return 1;    }    free(lpProtocolBuf);    WSACleanup();      cin>>iResult;    return iResult;      }
    Phần em bị vướng là hàm WSAWaitFormuti .... trong đoạn

    Mã:
     // goi lai ham WSAWaitForMultipleEventsindex = WSAWaitForMultipleEvents(event_total, EventArray, FALSE, 5000, FALSE);WSAEnumNetworkEvents(ConnectSocket,EventArray[index - WSA_WAIT_EVENT_0],&NetworkEvents);
    như vậy nếu dữ liệu của web gửi về đã hết ....thì sau 5 ( thời gian time out 5000 ) mới thông báo đã nhận xong dữ liệu . Như vậy là ko hợp lý ....các bác có cao kiến giúp e giải quyết vấn đề trong lần nhận cuối cùng không bị chờ cho hàm WSAWaitFor time out tới 5s mới thông báo kết quả . mà thông báo ngay sau khi đã nhận xong ...nếu có thể sử ký bằng đa luồng cũng được ạ !

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bạn đọc bài này: Lập Trình Mạng Với Thư Viện Winsock trên VC++
    Đơn giản là web browse chỉ đọc dữ liệu cho đến khi không đọc được nữa (giá trị trả về của recv == 0);
    Timeout chỉ là thời gian để chờ sever trả lời dữ liệu thôi, có thế do đường truyền hoặc lý do nào đó mà dữ liệu không đến kịp.

  3. #3
    Lâu rồi mới vào thread này, đọc kĩ lại mới thấy, bác này code vui quá.

    Mã:
    char * acc_encoding ="Accept-Encoding: gzip
    "
    Gửi kiểu này mà in response trong trong console thế nào cũng nghe tiếng bít bít vui tai. [IMG]images/smilies/smile.png[/IMG] Mã ASCII 7 phát tiếng bít ở loa speaker.

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •