|
|
![]() |
|
|
#1 |
|
Member
Tham gia ngày: May 2012
Bài gửi: 79
Online Status:
|
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 _ASSERTE( pThis != NULL ); pThis->Run(); return 1L; } // end SocketThreadProc |
|
|
|
#2 |
|
Member
Tham gia ngày: May 2012
Bài gửi: 63
Online Status:
|
Chương trình trên là do bộ đệm nhỏ thật, buffer = 256 bytes. |
|
| CHUYÊN MỤC ĐƯỢC TÀI TRỢ BỞI |
![]() |
|
|
| Công cụ bài viết | |
| Kiểu hiển thị | |
|
|