bool Port::FullRead(void *buffer, size_t length, OperationEnvironment &env, unsigned timeout_ms) { const TimeoutClock timeout(timeout_ms); char *p = (char *)buffer, *end = p + length; while (p < end) { WaitResult wait_result = WaitRead(env, timeout.GetRemainingOrZero()); if (wait_result != WaitResult::READY) // Operation canceled, Timeout expired or I/O error occurred return false; int nbytes = Read(p, end - p); if (nbytes <= 0) /* * Error occured, or no data read, which is also an error * when WaitRead returns READY */ return false; p += nbytes; if (timeout.HasExpired()) return false; } return true; }
bool Port::ExpectString(const char *token, OperationEnvironment &env, unsigned timeout_ms) { assert(token != NULL); const char *const token_end = token + strlen(token); const TimeoutClock timeout(timeout_ms); char buffer[256]; const char *p = token; while (true) { WaitResult wait_result = WaitRead(env, timeout.GetRemainingOrZero()); if (wait_result != WaitResult::READY) // Operation canceled, Timeout expired or I/O error occurred return false; int nbytes = Read(buffer, std::min(sizeof(buffer), size_t(token_end - p))); if (nbytes < 0 || env.IsCancelled()) return false; for (const char *q = buffer, *end = buffer + nbytes; q != end; ++q) { const char ch = *q; if (ch != *p) /* retry */ p = token; else if (++p == token_end) return true; } } }
bool Port::FullFlush(OperationEnvironment &env, unsigned timeout_ms, unsigned total_timeout_ms) { Flush(); const TimeoutClock total_timeout(total_timeout_ms); char buffer[0x100]; do { switch (WaitRead(env, timeout_ms)) { case WaitResult::READY: if (!Read(buffer, sizeof(buffer))) return false; break; case WaitResult::TIMEOUT: return true; case WaitResult::FAILED: case WaitResult::CANCELLED: return false; } } while (!total_timeout.HasExpired()); return true; }
int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags ) { #if defined(__sun__) || defined(sun) if (WaitRead() < 0) return -1; #endif return recv ( fSockfd, buffer, nbytes, flags ); }
int TTYPort::Read(void *Buffer, size_t Size) { if (WaitRead(rx_timeout) != WaitResult::READY) return -1; return read(fd, Buffer, Size); }
int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) { socklen_t addr_len = sizeof ( socket_address_t ); #if defined(__sun__) || defined(sun) if (WaitRead() < 0) return -1; #endif return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len ); }
/* *功能: 收数据 *输入参数: unsigned int nSize:缓冲区的长度 int timeout: 超时的毫秒数(1秒=1000毫秒) -1表阻塞式接收 0:不可收时立即返回,不等待 >0:不可收时等待至超时 *输出参数: char *chBuffer:缓冲区 *返回值: -1:失败,具体错误可以通过GetLastError()获取 0:对方已关闭 >0:收到的数据长度 */ int CBaseSocket::Recv(char *chBuffer, unsigned int nSize, int timeout /*= -1*/, int flags /*= 0*/) { if(timeout < 0) { return recv(m_iSocket, chBuffer, nSize, flags); } int n = WaitRead( timeout ); if(n != 0) { return n; } return recv(m_iSocket, chBuffer, nSize, flags); }
int main(int argc, char **argv) try { Args args(argc, argv, "PORT BAUD"); DebugPort debug_port(args); args.ExpectEnd(); ScopeGlobalAsioThread global_asio_thread; NullDataHandler handler; auto port = debug_port.Open(*asio_thread, handler); ConsoleOperationEnvironment env; if (!port->WaitConnected(env)) { fprintf(stderr, "Failed to connect the port\n"); return EXIT_FAILURE; } char buffer[4096]; while (true) { switch (port->WaitRead(env, std::chrono::minutes(1))) { case Port::WaitResult::READY: break; case Port::WaitResult::TIMEOUT: continue; case Port::WaitResult::FAILED: return EXIT_FAILURE; case Port::WaitResult::CANCELLED: return EXIT_SUCCESS; } int nbytes = port->Read(buffer, sizeof(buffer)); if (nbytes < 0) break; fwrite((const void *)buffer, 1, nbytes, stdout); } return EXIT_SUCCESS; } catch (const std::exception &exception) { PrintException(exception); return EXIT_FAILURE; }
void TTYPort::Run() { char buffer[1024]; while (true) { /* wait for data to arrive on the port */ switch (WaitRead(200)) { case WaitResult::READY: /* linger for a few more milliseconds so the device can send some more data; without this, we would be waking up for every single byte */ if (WaitForStopped(10)) return; break; case WaitResult::FAILED: if (errno != EAGAIN && errno != EINTR) { valid.Reset(); return; } /* non-fatal error, fall through */ case WaitResult::TIMEOUT: case WaitResult::CANCELLED: /* throttle */ if (WaitForStopped(500)) return; continue; } ssize_t nbytes = read(fd, buffer, sizeof(buffer)); if (nbytes == 0 || (nbytes < 0 && errno != EAGAIN && errno != EINTR)) { valid.Reset(); return; } if (nbytes > 0) handler.DataReceived(buffer, nbytes); } Flush(); }
Port::WaitResult Port::WaitRead(OperationEnvironment &env, unsigned timeout_ms) { unsigned remaining = timeout_ms; do { /* this loop is ugly, and should be redesigned when we have non-blocking I/O in all Port implementations */ const unsigned t = std::min(remaining, 500u); WaitResult result = WaitRead(t); if (result != WaitResult::TIMEOUT) return result; if (env.IsCancelled()) return WaitResult::CANCELLED; remaining -= t; } while (remaining > 0); return WaitResult::TIMEOUT; }
Port::WaitResult Port::WaitForChar(const char token, OperationEnvironment &env, unsigned timeout_ms) { const TimeoutClock timeout(timeout_ms); while (true) { WaitResult wait_result = WaitRead(env, timeout.GetRemainingOrZero()); if (wait_result != WaitResult::READY) // Operation canceled, Timeout expired or I/O error occurred return wait_result; // Read and compare character with token int ch = GetChar(); if (ch == token) break; if (timeout.HasExpired()) return WaitResult::TIMEOUT; } return WaitResult::READY; }
/* *功能: 收数据(一直收满nBytes字节为止,或者出错为止,或者超时为止) *输入参数: unsigned int &nBytes:缓冲区的长度 int timeout: 超时的毫秒数(1秒=1000毫秒) -1表阻塞式接收 0:不可收时立即返回,不等待 >0:不可收时等待至超时 int flags:标志 *输出参数: char *chBuffer:缓冲区中包含已收到的数据 *返回值: -2:timeout -1:失败,具体错误可以通过GetLastError()获取 0:对方已关闭 >0:收完了所有数据 */ int CBaseSocket::RecvN(unsigned int &nread, void *pBuffer, unsigned int nBytes,int timeout /*= -1*/, int flags /*= 0*/) { if(m_iSocket < 0) { return -1; } nread = 0; if( timeout < 0) { return ReadN(nread, pBuffer, nBytes); } struct timeval start; struct timezone tz; gettimeofday(&start, &tz); unsigned int left = nBytes; int n = 0; char *ptr = (char *)pBuffer; while(1) { n = WaitRead(timeout); if(n < 0) //error { //if(errno == ETIMEO) return n; //timeout } n = recv(m_iSocket, ptr, left, flags); if( n < 0) { if(errno == EINTR) { continue; } return -1; //error } if(n == 0) { return 0; //closed by peer } left -= n; ptr += n; nread += n; if(left <= 0) { break; //ok } timeout -= DiffMillSec(start); if(timeout <= 0) //timeout { return -2; } } if(nread == nBytes) { return nread; } return -2; //timeout }