Thông báo

Collapse
No announcement yet.

Help...Socket trong VC++

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Help...Socket trong VC++

    Em đang học lập trình giao tiếp theo chuẩn UDP bằng Socket trong VC++. Em lập trình server gửi dữ liệu cho client nhưng gửi với dữ liệu lớn thì không gửi được em tham khảo trên:
    http://www.codeproject.com/KB/IP/ser...w=Quick&fr=276
    với chương trình trên website em gửi dữ liệu nhỏ hơn 283bytes thì nhận được còn lớn hơn thì chương trình báo lỗi: "Connection Abandonned" .
    Mong các bác chỉ bảo: Nguyên nhân này do đâu? Liệu chương trình của em có phải do bộ đệm buffer nhỏ không? để truyền với các packet lớn (khoảng 900bytes) thì phải làm thế nào???
    ///////////////////////////////////////////////////////////////////////////////
    // ReadComm
    ///////////////////////////////////////////////////////////////////////////////
    // DESCRIPTION:
    // Reads the Socket Communication (doc giao tiep Socket)
    // PARAMETERS:
    // LPBYTE lpBuffer: buffer to place new data(vung dem de luu du lieu moi)
    // DWORD dwSize: maximum size of buffer (kich thuoc lon nhat cua vung dem)
    // DWORD dwTimeout: timeout to use in millisecond
    ///////////////////////////////////////////////////////////////////////////////
    DWORD CSocketComm::ReadComm(LPBYTE lpBuffer, DWORD dwSize, DWORD dwTimeout)
    {
    _ASSERTE( IsOpen() );
    _ASSERTE( lpBuffer != NULL );

    if (lpBuffer == NULL || dwSize < 1L)
    return 0L;

    fd_set fdRead = { 0 };
    TIMEVAL stTime;
    TIMEVAL *pstTime = NULL;

    if ( INFINITE != dwTimeout ) {
    stTime.tv_sec = dwTimeout/1000;
    stTime.tv_usec = (dwTimeout%1000)*1000;
    pstTime = &stTime;
    }

    SOCKET s = (SOCKET) m_hComm;
    // Set Descriptor
    if ( !FD_ISSET( s, &fdRead ) )
    FD_SET( s, &fdRead );

    // Select function set read timeout
    DWORD dwBytesRead = 0L;
    int res = select( s+1, &fdRead, NULL, NULL, pstTime );
    if ( res > 0)
    {
    if (IsBroadcast() || IsSmartAddressing())
    {
    SockAddrIn sockAddr;
    sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    int nLen = sockAddr.Size();
    int nOffset = IsSmartAddressing() ? nLen : 0; // use offset for Smart addressing
    if ( dwSize < (DWORD) nOffset) // error - buffer to small
    {
    SetLastError( ERROR_INVALID_USER_BUFFER );
    return -1L;
    }
    LPSTR lpszData = (LPSTR)(lpBuffer + nOffset);
    res = recvfrom( s, lpszData, dwSize-nOffset, 0, sockAddr, &nLen);

    // clear 'sin_zero', we will ignore them with 'SockAddrIn' anyway!
    memset(&sockAddr.sin_zero, 0, sizeof(sockAddr.sin_zero));

    // Lock the list...
    LockList();
    m_AddrList.remove( sockAddr );

    if ( res >= 0)
    {
    // insert unique address
    m_AddrList.insert(m_AddrList.end(), sockAddr);

    if (IsSmartAddressing())
    {
    memcpy(lpBuffer, &sockAddr, sockAddr.Size());
    res += sockAddr.Size();
    }
    }
    else if (WSAGetLastError() == WSAECONNRESET && m_AddrList.size() == 1)
    {
    // recvfrom doesn't always return the connection address for last connection
    m_AddrList.clear();
    }

    UnlockList(); // unlock this object addresses-list
    }
    else
    {
    res = recv( s, (LPSTR)lpBuffer, dwSize, 0);
    }
    }
    dwBytesRead = (DWORD)((res > 0)?(res) : (-1L));

    return dwBytesRead;
    }
    ///////////////////////////////////////////////////////////////////////////////
    // Run
    ///////////////////////////////////////////////////////////////////////////////
    // DESCRIPTION:
    // This function runs the main thread loop
    // this implementation can be overloaded.
    // This function calls CSocketComm::OnDataReceived() (Virtual Function)
    // PARAMETERS:
    // NOTES:
    // You should not wait on the thread to end in this function or overloads
    ///////////////////////////////////////////////////////////////////////////////
    void CSocketComm::Run()
    {
    stMessageProxy stMsgProxy;
    DWORD dwBytes = 0L;
    DWORD dwTimeout = INFINITE;
    LPBYTE lpData = (LPBYTE)&stMsgProxy;
    DWORD dwSize = sizeof(stMsgProxy);

    bool bSmartAddressing = IsSmartAddressing();
    if ( !bSmartAddressing )
    {
    lpData = stMsgProxy.byData;
    dwSize = sizeof(stMsgProxy.byData);
    }

    // Should we run as server mode
    if (IsServer() && !bSmartAddressing)
    {
    if (!IsBroadcast())
    {
    SOCKET sock = (SOCKET) m_hComm;
    sock = WaitForConnection( sock );

    // Get new connection socket
    if (sock != INVALID_SOCKET)
    {
    ShutdownConnection( (SOCKET) m_hComm);
    m_hComm = (HANDLE) sock;
    OnEvent( EVT_CONSUCCESS, NULL ); // connect
    }
    else
    {
    // Do not send event if we are closing
    if (IsOpen())
    OnEvent( EVT_CONFAILURE, NULL ); // wait fail
    return;
    }
    }
    }
    else
    {
    GetPeerName( stMsgProxy.address );
    }

    while( IsOpen() )
    {
    // Blocking mode: Wait for event
    dwBytes = ReadComm(lpData, dwSize, dwTimeout);

    // Error? - need to signal error
    if (dwBytes == (DWORD)-1L)
    {
    // Do not send event if we are closing
    if (IsOpen())
    {
    if ( bSmartAddressing )
    {
    RemoveFromList( stMsgProxy.address );
    }
    OnEvent( EVT_CONDROP, &stMsgProxy.address); // lost connection
    }

    // special case for UDP, alert about the event but do not stop
    if ( bSmartAddressing )
    continue;
    else
    break;
    }

    // Chars received?
    if ( bSmartAddressing && dwBytes == sizeof(SOCKADDR_IN))
    {
    OnEvent( EVT_ZEROLENGTH, NULL );
    }
    else if (dwBytes > 0L)
    {
    OnDataReceived( lpData, dwBytes);
    }

    Sleep(0);
    }
    }


    ///////////////////////////////////////////////////////////////////////////////
    // SocketThreadProc
    ///////////////////////////////////////////////////////////////////////////////
    // DESCRIPTION:
    // Socket Thread function. This function is the main thread for socket
    // communication - Asynchronous mode.
    // PARAMETERS:
    // LPVOID pParam : Thread parameter - a CSocketComm pointer
    // NOTES:
    ///////////////////////////////////////////////////////////////////////////////
    UINT WINAPI CSocketComm::SocketThreadProc(LPVOID pParam)
    {
    CSocketComm* pThis = reinterpret_cast<CSocketComm*>( pParam );
    _ASSERTE( pThis != NULL );

    pThis->Run();

    return 1L;
    } // end SocketThreadProc
    Benado Tran

  • #2
    Chương trình trên là do bộ đệm nhỏ thật, buffer = 256 bytes.
    Benado Tran

    Comment

    Về tác giả

    Collapse

    tranthuyet Vui vẻ-nhiệt tình Tìm hiểu thêm về tranthuyet

    Bài viết mới nhất

    Collapse

    Đang tải...
    X