banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận mạng và thiết bị mạng Recv bị đứng khi lập trình Winsock  XML
  [Question]   Recv bị đứng khi lập trình Winsock 01/07/2012 17:22:34 (+0700) | #1 | 265874
[Avatar]
chiro8x
Member

[Minus]    0    [Plus]
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
[Profile] [PM] [Yahoo!]
Em đang tập tành lập trình trên windows trở lại, nên bắt tay viết một số cái demo code. Nhưng mà dạo này thức khuya nhiều em cứ như thằng bại não thế này. Anh em nào giúp em với giờ em thấy bí rồi.

Code:
#include <stdio.h>
#include <stdlib.h>
//#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string.h>
//#define MAKEWORD2(L,H) (H<<8)|L


#define ERF_NONE 0
#define ERF_GETHOST 1
#define ERF_CREATESCK 2
#define ERF_CONNECFAIL 3
#define ERF_STARTUPFAIL 4
int main()
{
    SOCKET sckID;
    WSADATA wsaData;
    SOCKADDR_IN sckAddr;
    unsigned int sckPort = 80;
    char *sckHost = "truyen.vnsharing.net";
    HOSTENT *sckHostent;
    int errorFlag = ERF_NONE;

    //Winsock application startup
    if(errorFlag == ERF_NONE)
        if( WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR )
            errorFlag = ERF_STARTUPFAIL;
/**-------------------------------------------------------------------**/
    //Get host by name
    if(errorFlag == ERF_NONE)
        if( (sckHostent = gethostbyname(sckHost)) == NULL )
            errorFlag = ERF_GETHOST;

    //Init data
    if( errorFlag == ERF_NONE ){
        memset(&sckAddr, 0x00, sizeof(SOCKADDR_IN));
        sckAddr.sin_family = AF_INET;
        sckAddr.sin_port = htons(sckPort);
        //sckAddr.sin_addr.s_addr = inet_addr("120.138.69.101");
        sckAddr.sin_addr = *((IN_ADDR*)sckHostent->h_addr);
    }
/**-------------------------------------------------------------------**/
    //Create socket
    if( errorFlag == ERF_NONE)
        if( (sckID = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET )
           errorFlag = ERF_CREATESCK;

    //Connect now
    if( errorFlag == ERF_NONE )
        if( connect(sckID, (SOCKADDR *)&sckAddr, sizeof(SOCKADDR)) == SOCKET_ERROR )
            errorFlag = ERF_CONNECFAIL;

/**-------------------------------------------------------------------**/

    size_t bzBytes = 0;
    size_t sendBytes = 0;
    size_t rcvBytes = 0;
    char *ptr_sent;
    char *ptr_rcv = malloc(1024);


    char ptr_tmp[1025];
    BOOL csflag = TRUE;


    ptr_sent = "GET / HTTP/1.1\nHost: truyen.vnsharing.net\n\n";

    send(sckID,ptr_sent, strlen(ptr_sent),0 );

    size_t t = 0;

    do{
        memset(ptr_tmp,0x00,1025);
        rcvBytes = recv(sckID, &ptr_tmp, 1024, 0);
        printf("%s",&ptr_tmp);

        if ( rcvBytes > 0 )
            printf("Bytes received: %d\n", rcvBytes);
        else if ( rcvBytes == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    }while( rcvBytes > 0 );
    /*
    while( rcvBytes > 0 || csflag == TRUE ){
        //Clear temp buffer
        csflag = FALSE;
        memset(ptr_tmp,0x00,1025);
        rcvBytes = recv(sckID, &ptr_tmp, 1024, 0);

        if(rcvBytes > 0){

            realloc(ptr_rcv, ( bzBytes + rcvBytes ) );
            //memset( ( ptr_rcv + bzBytes), 0x00, rcvBytes );
            memcpy( ( ptr_rcv + bzBytes) , &ptr_tmp, rcvBytes );
            bzBytes = bzBytes + rcvBytes;
            //printf("%s", &ptr_tmp);

        }* /


        printf("%d\n", bzBytes);
        printf("->%d\n", rcvBytes);


        t++;
        printf("\n%d\n", t);

    }*/

    printf("\nData:\n\n%s", ptr_rcv);
    closesocket(sckID);
    WSACleanup();
    free(ptr_rcv);
    free(ptr_tmp);

    return 0;
}

Chuyện là thế này ! em muốn gửi một binary file (chẳng hạn như quá trình update của soft chẳng hạn, kích thước nó không quá lớn). Khi viết thử mã trên em dbg gặp lỗi ở memcpy(). Em thử lại xem winsock có lỗi gì không. Thì thấy là khi thực thi nó bị đứng, mặc dù em chưa biết nguyên nhân nằm đâu, WSAGetLastError() = 0. rcvBytes nó cũng bình thường, nhưng cái vòng lặp do{}while cứ ở trạng thái idle mãi.
while(1){}
[Up] [Print Copy]
  [Question]   Recv bị đứng khi lập trình Winsock 02/07/2012 21:10:44 (+0700) | #2 | 265975
[Avatar]
chiro8x
Member

[Minus]    0    [Plus]
Joined: 26/09/2010 00:38:37
Messages: 661
Location: /home/chiro8x
Offline
[Profile] [PM] [Yahoo!]
Vấn đề trên đã được em giải quyết như sau, nếu có gì không thoản đáng xin được giúp đỡ.

Đăt receiving timeout & sending timeout:
Code:
setsockopt(sckID, SOL_SOCKET, SO_RCVTIMEO, (char *)&sckRcvt, sizeof(DWORD));
    setsockopt(sckID, SOL_SOCKET, SO_SNDTIMEO, (char *)&sckSendt, sizeof(DWORD));


Sửa lại đoạn này:
Code:
size_t rcvBytes = 0;

Thành:
Code:
int rcvBytes = 0;
while(1){}
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|