// // handle_input // int CUTS_TCPIP_Event_Handler::handle_input (ACE_HANDLE fd) { // Set the ACE_HANDLE as a socket stream. ACE_SOCK_Stream stream (fd); // @todo Since the header size is constant, we can create free list // of the message blocks that are used to read the header from // the stream. // Read the event from the stream. The first chunk of the event // is be the header information, which is of constrant size. static const ssize_t header_size = 4 + // magic 4 + // byte order 2 + // version (x.x) 2 + // padding 16 + // UUID 4 + // event id 4; // payload size ACE_Message_Block header (header_size); ssize_t retcode = stream.recv_n (header.wr_ptr (), header_size); if (retcode != header_size) ACE_ERROR_RETURN ((LM_ERROR, "%T (%t) - %M - invalid TCP/IP header\n"), -1); // Reflect the number of bytes read from the stream. header.wr_ptr (header_size); // Extract the header from the message block. CUTS_TCPIP_SPEC spec; ACE_CDR::ULong datasize; ACE_InputCDR input (header.rd_ptr (), header_size); // Read the SPEC and the datasize from the packet. input >> spec; input >> datasize; if (!input.good_bit ()) ACE_ERROR_RETURN ((LM_ERROR, "%T (%t) - %M - failed to read TCP/IP header\n"), -1); // Construct a chain of message blocks to read the payload associated // with the received event. ACE_Message_Block * mb = 0; ACE_NEW_RETURN (mb, ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE), -1); ssize_t read_count; ACE_Message_Block * head = mb; ACE_Auto_Ptr <ACE_Message_Block> auto_clean (head); for (size_t remaining = datasize; 0 != remaining; ) { // Determine how much should be read in this attempt. read_count = ACE_CDR::DEFAULT_BUFSIZE < remaining ? ACE_CDR::DEFAULT_BUFSIZE : remaining; // Read the data from the stream. retcode = stream.recv_n (mb->wr_ptr (), read_count); if (retcode != read_count) ACE_ERROR_RETURN ((LM_ERROR, "%T - %M - %m\n"), -1); // Substract the amount from the remaining count. mb->wr_ptr (read_count); remaining -= read_count; if (0 != remaining) { // Allocate a new block for the chain. ACE_Message_Block * temp = 0; ACE_NEW_RETURN (temp, ACE_Message_Block (ACE_CDR::DEFAULT_BUFSIZE), -1); // Insert new block in the chain and move forward. mb->cont (temp); mb = temp; } } // Since we have made it this far, we have successfully read the // event and its payload from the socket. Now, pass the message // the object manger, so it can dispatch it accordingly. if (this->obj_mgr_ != 0) { iCCM::TCPIP_Servant * svnt = 0; int retval = this->obj_mgr_->find_object (spec.uuid_, svnt); if (0 == retval) { // Signal the object to handle the event. ACE_InputCDR ev (head, input.byte_order ()); retval = svnt->handle_event (spec.event_id_, ev); if (-1 == retval) ACE_ERROR ((LM_ERROR, "%T (%t) - %M - failed to handle event [%s]\n", spec.uuid_.to_string ()->c_str ())); } else ACE_ERROR ((LM_ERROR, "%T (%t) - %M - failed to locate object with id [%s]\n", spec.uuid_.to_string ()->c_str ())); } // Release the message block. // head->release (); return 0; }
// thread function that serves the client for the UnMarshalled Octet // test static ACE_THR_FUNC_RETURN unmarshalledOctetServer (void *arg){ // unbundle the arguments ArgStruct * args = reinterpret_cast<ArgStruct *> (arg); ACE_SOCK_Stream * dataModeStream = args->stream; ACE_CDR::ULong numIterations = args->numIters; delete args; // serve the client for numIterations synchronous invocations do { // READ A MESSAGE FROM THE CLIENT size_t bt; ACE_CDR::ULong msgBufSize=0; // read the size of the buffer to follow if ((dataModeStream->recv_n(&msgBufSize, ACE_CDR::LONG_SIZE, 0, &bt)) == -1) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv_n")), 0); msgBufSize = ACE_NTOHL(msgBufSize); // allocate the buffer for the message payload ACE_CDR::Octet * msgBuf = 0; ACE_NEW_RETURN(msgBuf, ACE_CDR::Octet[msgBufSize], 0); // read the buffer if ((dataModeStream->recv_n(msgBuf, msgBufSize, 0, &bt)) == -1) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv_n")), 0); // clean up the allocated buffer delete[] msgBuf; // SEND A REPLY TO THE CLIENT // send back a 2 byte reply ACE_CDR::Short reply; if ((dataModeStream->send_n(&reply, ACE_CDR::SHORT_SIZE, 0, &bt)) == -1) ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("send_n")), 0); } while (--numIterations); // close and destroy the stream dataModeStream->close(); delete dataModeStream; return 0; }
void JAWS_Synch_IO::receive_file (JAWS_IO_Handler *ioh, const char *filename, void *initial_data, unsigned int initial_data_length, unsigned int entire_length) { ACE_Filecache_Handle handle (filename, (int) entire_length); int result = handle.error (); if (result == ACE_Filecache_Handle::ACE_SUCCESS) { ACE_SOCK_Stream stream; stream.set_handle (ioh->handle ()); int bytes_to_memcpy = ACE_MIN (entire_length, initial_data_length); ACE_OS::memcpy (handle.address (), initial_data, bytes_to_memcpy); int bytes_to_read = entire_length - bytes_to_memcpy; int bytes = stream.recv_n ((char *) handle.address () + initial_data_length, bytes_to_read); if (bytes == bytes_to_read) ioh->receive_file_complete (); else result = -1; } if (result != ACE_Filecache_Handle::ACE_SUCCESS) ioh->receive_file_error (result); }
void JAWS_Synch_IO::receive_file (const char *filename, void *initial_data, int initial_data_length, int entire_length) { ACE_Filecache_Handle handle (ACE_TEXT_CHAR_TO_TCHAR (filename), entire_length); int result = handle.error (); if (result == ACE_Filecache_Handle::ACE_SUCCESS) { ACE_SOCK_Stream stream; stream.set_handle (this->handle_); int bytes_to_memcpy = ACE_MIN (entire_length, initial_data_length); ACE_OS::memcpy (handle.address (), initial_data, bytes_to_memcpy); int bytes_to_read = entire_length - bytes_to_memcpy; int bytes = stream.recv_n ((char *) handle.address () + initial_data_length, bytes_to_read); if (bytes == bytes_to_read) this->handler_->receive_file_complete (); else result = -1; } if (result != ACE_Filecache_Handle::ACE_SUCCESS) this->handler_->receive_file_error (result); }
bool MgAceStreamHelper::IsConnected() { bool bConnected = true; ACE_SOCK_Stream stream; stream.set_handle( m_handle ); UINT8 dummy; ACE_Time_Value val(0, 0); ssize_t res = stream.recv_n(&dummy, 1, MSG_PEEK | MG_MSG_NOSIGNAL, &val); if ( res < 0 ) { // Error or timeout occured #ifdef _WIN32 int error = ::WSAGetLastError(); // errno doesn't work correctly on Windows bConnected = ( error == WSAEWOULDBLOCK || error == 0 ); #else bConnected = ( errno == EWOULDBLOCK || errno == 0 || errno == ETIME ); #endif } else if (res == 0) { // No longer connected bConnected = false; } return bConnected; }
int logClient::process(ACE_CString* s){ ACE_SOCK_Stream logger; ACE_SOCK_Connector connector; ACE_INET_Addr addr(9876, "127.0.0.1"); if(connector.connect(logger, addr) == -1){ ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p \n"), ACE_TEXT("open")), -1); } ACE_Log_Record record(LM_DEBUG, ACE_OS::time ((time_t *) 0), ACE_OS::getpid()); record.msg_data(s.c_str()); const size_t max_payload_size = 4 + 8 + 4 + 4 + ACE_Log_Record::MAXLOGMSGLEN + ACE_CDR::MAX_ALIGNMENT; ACE_OutputCDR payload(max_payload_size); payload<< record; ACE_CDR::ULong length = ACE_Utils::truncate_cast<ACE_CDR::ULong> (payload.total_length()); ACE_OutputCDR header (ACE_CDR::MAX_ALIGNMENT + 8); header << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER); header << ACE_CDR::ULong(length); iovec iov[2]; iov[0].iov_base = header.begin() -> rd_ptr(); iov[0].iov_len = 8; iov[1].iov_base = payload.begin() -> rd_ptr(); iov[1].iov_len = length; if (logger.sendv_n(iov, 2) == -1) ACE_ERROR_RETURN((LM_ERROR,"%p\n","send"), -1); /* */ ACE_Message_Block* header_p; auto_ptr<ACE_Message_Block> header(header_p); ACE_CDR::mb_align(header.get()); ACE_Message_Block* payload_p; ssize_t count = logger.recv_n(header->wr_ptr(),8); switch(count){ default: case -1: case 0: case 8: break; } header->wr_ptr(8); }
int handle_input(ACE_HANDLE) { if(Peer->recv_n(data, DATA_SIZE) == 0) { std::cout<<"Peer probably aborted connection"; ACE_Thread::cancel(t_id); return -1; } ACE_OS::printf("<< %s\n", data); return 0; }
void read_thread(void* arg) { pa_sample_spec capture_profile; capture_profile.channels = 1; capture_profile.rate = 44100; capture_profile.format = PA_SAMPLE_S16LE; int error; int m = *(int*)arg; pa_simple *paPlayHandle = pa_simple_new(NULL,"soundCard", PA_STREAM_PLAYBACK, NULL, "playback", &capture_profile, NULL, NULL, &error); for (int i = 0; i < m; i++) { short buffer[2048]; if(server.recv_n(buffer,2048) > 0) pa_simple_write(paPlayHandle, buffer, 2048, &error); } }
int handle_connection(){ for (int i = 0; i < NO_ITERATIONS; i++){ int byte_count = 0; if ((byte_count = new_stream_.recv_n(data_buf_, SIZE_DATA, 0)) == -1){ ACE_ERROR((LM_ERROR, "%p\n", "Error in recv")); } else{ data_buf_[byte_count] = 0; ACE_DEBUG((LM_DEBUG, "Server received %s \n", data_buf_)); } } if (new_stream_.close() == -1){ ACE_ERROR((LM_ERROR,"%p\n","close")); } return 0; }
// sets up the dataModeSocket Stream, reads the test header infomation // and launches a thread to handle the requested test. static void run_server (ACE_HANDLE handle) { ACE_INET_Addr cli_addr; // create a new stream and initialized with the handle returned by // accept ACE_SOCK_Stream * dataModeStream = new ACE_SOCK_Stream; dataModeStream->set_handle (handle); // Make sure we're not in non-blocking mode. if (dataModeStream->disable (ACE_NONBLOCK) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("disable"))); return; } else if (dataModeStream->get_remote_addr (cli_addr) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("get_remote_addr"))); return; } // explicity configure Nagling. Default is // Options_Manager::test_enable_nagle=0 so default configurations is // NO NAGLING ACE_CDR::Long nagle; if (Options_Manager::test_enable_nagle) nagle=0; else nagle=1; if (Options_Manager::test_transport_protocol == IPPROTO_SCTP){ // default - sctp case if (-1 == dataModeStream->set_option(IPPROTO_SCTP, SCTP_NODELAY, &nagle, sizeof nagle)){ ACE_ERROR((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_option"))); return; } } else { // tcp case if (-1 == dataModeStream->set_option(IPPROTO_TCP, TCP_NODELAY, &nagle, sizeof nagle)){ ACE_ERROR ((LM_ERROR, "%p\n", "set_option")); return; } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) client %C connected from %d\n"), cli_addr.get_host_name (), cli_addr.get_port_number ())); // hdr bufSize is hardcoded to 8 bytes // (4 for a CDR-encoded boolean and 4 for a CDR-encoded ULong) ACE_CDR::ULong hdrBufSize = 8; // allocate a raw buffer large enough to receive the header and be // properly aligned for the CDR decoding. ACE_CDR::Char * hdrBuf= new ACE_CDR::Char[hdrBufSize+ACE_CDR::MAX_ALIGNMENT]; // align the raw buffer before reading data into it. char * hdrBuf_a = ACE_ptr_align_binary(hdrBuf, ACE_CDR::MAX_ALIGNMENT); size_t bt; // read the header if ((dataModeStream->recv_n(hdrBuf_a, hdrBufSize, 0, &bt)) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv_n"))); return; } // pass the CDR encoded data into an ACE_InputCDR class. hdrCDR does // NOT copy this data. Nor does it delete. It assumes the buffer // remains valid while it is in scope. ACE_InputCDR hdrCDR(hdrBuf_a, hdrBufSize); ACE_CDR::Boolean byteOrder; ACE_CDR::ULong numIterations; // extract the data hdrCDR >> ACE_InputCDR::to_boolean (byteOrder); hdrCDR.reset_byte_order(byteOrder); hdrCDR >> numIterations; // make sure the stream is good after the extractions if (!hdrCDR.good_bit()){ ACE_ERROR((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("hdrCDR"))); return; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Test for %u iterations\n"), numIterations)); // deallocate the header buffer delete[] hdrBuf; // bundle up the arguments ArgStruct * args = new ArgStruct; args->stream = dataModeStream; args->numIters = numIterations; #if defined (ACE_HAS_THREADS) // Spawn a new thread and run the new connection in that thread of // control using the <server> function as the entry point. if (ACE_Thread_Manager::instance ()->spawn (unmarshalledOctetServer, reinterpret_cast<void *> (args), THR_DETACHED) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("spawn"))); #else (*unmarshalledOctetServer) (reinterpret_cast<void *> (args)); #endif /* ACE_HAS_THREADS */ }
int ACE_TMAIN(int argc, ACE_TCHAR **argv) { // size and count for transmissions int size = 0, count = -1; // the server's answer is a single byte char answer; // parse the <size> argument if ((argc < 2) || (((size = ACE_OS::strtol(argv[1], 0, 10)) < 1) || (errno == EINVAL))) return printUsage(argv[0]); // take size as the number of MiB and create appropriate buffer size *= BASE; char *someData = new (std::nothrow) char[size]; if (someData == 0) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%N:%l: Failed to allocate ") ACE_TEXT ("data buffer.\n")), -1); // put someData in an auto_ptr so it gets deleted automatically auto_ptr<char> pSomeData(someData); // parse the <count> argument if available if ((argc == 3) && (((count = ACE_OS::strtol(argv[2], 0, 10)) < 1) || (errno == EINVAL))) return printUsage(argv[0]); // the server listens on localhost on default port (from common.h) ACE_INET_Addr serverAddr(PORT, "localhost"); ACE_SOCK_Stream stream; ACE_SOCK_Connector connector; // -1 is running indefinitely while ((count == -1) || (count-- != 0)) { // some output, that we know something is happening //ACE_DEBUG((LM_DEBUG, ACE_TEXT("%N:%l: Passes left: %i\n"), count)); ACE_DEBUG((LM_DEBUG, ACE_TEXT("."))); // connect to the server and get the stream if (connector.connect(stream, serverAddr) == -1) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to connect to ") ACE_TEXT ("server. (errno = %i: %m)\n"), ACE_ERRNO_GET)); break; } try { // send the request to the server (number of MiB in the next call) // Note: only use the sizeof and pointer to int on compatible // platforms (i.e. little-endian/big-endian, data type size) if (stream.send_n(&size, sizeof(size), &connTimeout) != sizeof(size)) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ") ACE_TEXT ("request. (errno = %i: %m)\n"), ACE_ERRNO_GET)); throw 1; } // receive the answer if (stream.recv_n(&answer, sizeof(answer), &connTimeout) != 1) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N: %l: Failed to receive ") ACE_TEXT ("1st response. (errno = %i: %m)\n"), ACE_ERRNO_GET)); throw 1; } // server answer, 'K" indicates a positive answer if (answer == 'K') { // send a huge message to the server if (stream.send_n(someData, size, &connTimeout) != size) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ") ACE_TEXT ("someData. (errno = %i: %m)\n"), ACE_ERRNO_GET)); throw 1; } // get an answer if (stream.recv_n(&answer, sizeof(answer), &connTimeout) != 1) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N: %l: Failed to receive ") ACE_TEXT ("2nd response. (errno = %i: %m)\n"), ACE_ERRNO_GET)); throw 1; } // check the answer if (answer != 'K') { cout << "The server was unable to process the data." << endl; } } } catch (...) { // ok we know an error occurred, we need to close the socket. // The we'll try again. } // close the current stream if (stream.close() == -1) { ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close ") ACE_TEXT ("socket. (errno = %i: %m)\n"), ACE_ERRNO_GET)); break; } } // while cout << "Bye. Bye" << endl; return 0; }
// conduct the UnMarshalled Octet performance test using separate // send_n calls with Nagle's algorithm disabled ACE_SCTP::HIST runUnmarshalledOctetTest(ACE_CDR::Octet *buf, size_t seqLen, ACE_SOCK_Stream & stream){ ACE_CDR::ULong const testIterations = Options_Manager::test_iterations; size_t bt; ACE_CDR::ULong cnt = 0; // variables for the timing measurements ACE_hrtime_t startTime, endTime; ACE_CDR::Double messageLatency_usec = 0.0; ACE_CDR::ULong msgLen = seqLen*ACE_CDR::OCTET_SIZE; // explicity configure Nagling. Default is // Options_Manager::test_enable_nagle=0 so default configurations is // NO NAGLING ACE_CDR::Long nagle; if (Options_Manager::test_enable_nagle) nagle=0; else nagle=1; if (Options_Manager::test_transport_protocol == IPPROTO_SCTP){ // default - sctp case if (-1 == stream.set_option(IPPROTO_SCTP, SCTP_NODELAY, &nagle, sizeof nagle)) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_option"), 0); } else { // tcp case if (-1 == stream.set_option(IPPROTO_TCP, TCP_NODELAY, &nagle, sizeof nagle)) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "set_option"), 0); } // prime the client and server before starting the test for(cnt=0;cnt<primerIterations;++cnt){ // send message size // TODO : The message length should be CDR encoded ACE_CDR::ULong msgLenExpressed = ACE_HTONL(msgLen); if (-1 == stream.send_n (&msgLenExpressed, ACE_CDR::LONG_SIZE, 0, &bt)) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 0); // send a message if (-1 == stream.send_n (buf, msgLen, 0, &bt)) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 0); // block for a Short reply ACE_CDR::Short reply; if ((stream.recv_n(&reply, ACE_CDR::SHORT_SIZE, 0, &bt)) == -1) ACE_ERROR_RETURN((LM_ERROR, "%p\n", "recv_n"), 0); } // AFTER PRIMING THE PUMP CREATE THE HISTOGRAM ACE_SCTP::HIST aceStream_hist = 0; aceStream_hist = createHistogram(msgLen); if (0 == aceStream_hist) ACE_ERROR_RETURN((LM_ERROR, "%p\n", "histogram create failed"), 0); iovec iov[2]; // PERFORMANCE TEST LOOP for (cnt = 0; cnt < testIterations; ++cnt){ // get the start time startTime = ACE_OS::gethrtime(); if (!startTime) ACE_ERROR_RETURN((LM_ERROR, "%p\n", "ACE_OS::gethrtime()"), 0); ACE_CDR::ULong msgLenExpressed = ACE_HTONL(msgLen); iov[0].iov_base = reinterpret_cast<char *> (&msgLenExpressed); iov[0].iov_len = ACE_CDR::LONG_SIZE; iov[1].iov_base = reinterpret_cast<char *> (buf); iov[1].iov_len = msgLen; if (-1 == stream.sendv_n (iov, 2)) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_n"), 0); // block for a Short reply ACE_CDR::Short reply; if ((stream.recv_n(&reply, ACE_CDR::SHORT_SIZE, 0, &bt)) == -1) ACE_ERROR_RETURN((LM_ERROR, "%p\n", "recv_n"), 0); // get the end time endTime = ACE_OS::gethrtime(); if (!endTime) ACE_ERROR_RETURN((LM_ERROR, "%p\n", "ACE_OS::gethrtime()"), 0); // compute the message latency in micro-seconds messageLatency_usec = (static_cast<double> (ACE_UINT64_DBLCAST_ADAPTER(endTime)) - static_cast<double> (ACE_UINT64_DBLCAST_ADAPTER(startTime))) / microsec_clock_scale_factor; // record the message latency in the histogram ACE_SCTP::record(messageLatency_usec, aceStream_hist); } // THE HEADER MESSAGE SENT TO THE SERVER CONTAINED THE NUMBER OF // PRIMER AND TEST MESSAGES TO BE SENT AFTER WHICH THE SERVER WILL // CLOSE THE STREAM SO ONCE WE REACH THIS POINT THE STREAM IS NO // LONGER VALID AND WE CLOSE IT. stream.close(); // allocated by runTest delete[] buf; return aceStream_hist; }
/////////////////////////////////////////////////////////////////////////// // <summary> // This method reads data from the stream into the given buffer. The // parameters control whether or not the read blocks, whether or not, // the caller wants to peek at the data, and if the caller wants to // know how many bytes had been read. // </summary> // // <param name = "buffer"> // The buffer that will receive the data read from the stream. // </param> // // <param name = "size"> // The size of the buffer in bytes of the buffer. // </param> // // <param name = "blocking"> // True if the read request should block; false otherwise. // </param> // // <param name = "peeking"> // True if the read request should not consume the data; false // otherwise. // </param> // // <param name = "bytesAvailable"> // An out parameter that will contain the number of bytes that have been // read from the stream. It will contain -1 if there was an error. // </param> // // <returns> // Returns a MgStreamStatus value indicating the status of the operation. // </returns> MgStreamHelper::MgStreamStatus MgAceStreamHelper::GetData(void* buffer, size_t size, bool blocking, bool peeking) { // Do not attempt reading zero byte from the socket as this could be problematic. if (0 == size) { return MgStreamHelper::mssDone; } ACE_ASSERT( size > 0 ); MgStreamHelper::MgStreamStatus stat = MgStreamHelper::mssError; // Is our internal buffer big enough? If not, expand it. if ( m_readBufSize < size ) { m_readBufSize = size; UINT8* temp = new UINT8[m_readBufSize]; memcpy( temp, &m_readBuffer[m_readBufStart], m_readBufEnd - m_readBufStart ); delete[] m_readBuffer; m_readBuffer = temp; m_readBufEnd -= m_readBufStart; m_readBufStart = 0; } // check if requested data is already in buffer stat = UpdateReadBuffers( buffer, size, peeking ); if ( MgStreamHelper::mssDone != stat ) { // We do not have enough data and will need to read. Shift buffer back // and attempt to fill the entire buffer with a non-blocking read first memmove(m_readBuffer, &m_readBuffer[m_readBufStart], m_readBufEnd-m_readBufStart); m_readBufEnd -= m_readBufStart; m_readBufStart = 0; ACE_SOCK_Stream stream; stream.set_handle( m_handle ); // Windows has a timing problem. If trying to receive data too fast, // it will fail. So, use a timeout to let it catch up. // This workaround reduces the number of lockups significantly and // eliminates the hanging problem when it takes so long to write a // request to the socket. const ACE_Time_Value timeout(60); // On Linux, use MSG_NOSIGNAL to turn off raising of SIGPIPE on // stream sockets when the other end disappears. // Note that neither trapping the SIGPIPE signal via an // ACE_Event_Handler nor calling ACE_OS::signal(SIGPIPE, SIG_IGN) // seems to work. ssize_t res = stream.recv(&m_readBuffer[m_readBufEnd], m_readBufSize - m_readBufEnd, MG_MSG_NOSIGNAL, &timeout); if ( res < 0 ) { // Check this return value to determine if the socket is closed or // if there was simply no data. #ifdef _WIN32 int error = ::WSAGetLastError(); // errno doesn't work correctly on Windows bool bConnected = ( error == WSAEWOULDBLOCK || error == 0 ); #else bool bConnected = ( errno == EWOULDBLOCK || errno == 0 || errno == ETIME ); #endif stat = ( bConnected ) ? MgStreamHelper::mssNotDone : MgStreamHelper::mssError; } else if (res == 0) { // No longer connected stat = MgStreamHelper::mssError; } else { m_readBufEnd += res; // Now do we have enough data? stat = UpdateReadBuffers( buffer, size, peeking ); } if (MgStreamHelper::mssNotDone == stat && blocking) { // Still not enough data. Have to block and fill only what was asked for. res = stream.recv_n(&m_readBuffer[m_readBufEnd], size - (m_readBufEnd-m_readBufStart), MG_MSG_NOSIGNAL); if ( res < 0 ) { // Check this return value to determine if the socket is closed or // if there was simply no data. #ifdef _WIN32 int error = ::WSAGetLastError(); // errno doesn't work correctly on Windows bool bConnected = ( error == WSAEWOULDBLOCK || error == 0 ); #else bool bConnected = ( errno == EWOULDBLOCK || errno == 0 || errno == ETIME ); #endif stat = ( bConnected ) ? MgStreamHelper::mssNotDone : MgStreamHelper::mssError; } else if (res == 0) { // No longer connected stat = MgStreamHelper::mssError; } else { m_readBufEnd += res; // Now we better have enough data... stat = UpdateReadBuffers( buffer, size, peeking ); } } } return stat; }
int Measuring_Task::svc () { this->the_barrier_->wait (); ACE_SOCK_Stream stream; { ACE_INET_Addr remote_sap (this->endpoint_); ACE_SOCK_Connector connector; if (connector.connect(stream, remote_sap) == -1) { ACE_ERROR((LM_ERROR, "Cannot connect to <%s>\n", endpoint_)); return -1; } } for (int i = 0; i != this->iterations_; ++i) { ACE_Time_Value period (0, this->period_in_usecs_); ACE_OS::sleep (period); ACE_hrtime_t start = ACE_OS::gethrtime (); ssize_t n = stream.send_n(&start, sizeof(start)); if (n == 0) { ACE_ERROR((LM_ERROR, "Connection closed while writing data to server <%s>\n", endpoint_)); break; } else if (n == -1) { ACE_ERROR((LM_ERROR, "Error writing data to server <%s> %p\n", endpoint_)); break; } if (n == 0 || n == -1) { ACE_ERROR((LM_ERROR, "Error sending data to server <%s>\n", endpoint_)); break; } ACE_hrtime_t end; n = stream.recv_n(&end, sizeof(end)); if (n == 0) { ACE_ERROR((LM_ERROR, "Connection closed while reading data from server <%s>\n", endpoint_)); break; } else if (n == -1) { ACE_ERROR((LM_ERROR, "Error reading data from server <%s> %p\n", endpoint_)); break; } if (start != end) { ACE_ERROR((LM_ERROR, "Mismatched response from <%s>\n", endpoint_)); return -1; } ACE_hrtime_t elapsed = ACE_OS::gethrtime () - start; this->sample_history.sample (elapsed); } stream.close(); return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { parse_args (argc, argv); ACE_INET_Addr sa (port_number, host_name); void *cp; char buf[BUFSIZ]; int n; ACE_SOCK_CODgram dc; if (dc.open (sa, ACE_Addr::sap_any) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); // First send the name of the file as a datagram. iovec iov[2]; iov[0].iov_base = (char *) "filename: "; iov[0].iov_len = 11; iov[1].iov_base = (char *) file_name; iov[1].iov_len = ACE_OS::strlen (file_name); if (dc.send (iov, 2) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); ACE_SOCK_Stream sc; ACE_SOCK_Connector con; if (con.connect (sc, sa) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "connect"), -1); ACE_Mem_Map mmap (file_name); if (mmap (cp) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "mmap"), -1); // Next, send the file's contents. if (sc.send_n (cp, mmap.size ()) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_urg"), -1); if (sc.close_writer () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close_writer"), -1); if ((n = sc.recv_n (buf, sizeof buf)) == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); else ACE_OS::write (ACE_STDOUT, buf, n); return 0; }