int SOYALDevice::make_handler(KSGDeviceNode* node,ACE_HANDLE* handler) { if(!node) return -1; std::string ip = node->GetDevAddr().GetConnect(); int port = node->GetDevAddr().GetPort(); ACE_INET_Addr addr(port,ip.c_str()); ACE_SOCK_Connector conn; ACE_SOCK_Stream stream; ACE_Time_Value tv = KSGGetTaskTimeoutIntval(); int err_code; ACE_DEBUG((LM_TRACE,"开始连接soyal控制器,[%s][%s]",node->get_name().c_str(),ip.c_str())); if(conn.connect(stream,addr,&tv)) { err_code = ACE_OS::last_error(); // TODO: 返回连接的错误码 if(EWOULDBLOCK == err_code) { ACE_DEBUG((LM_ERROR,"连接控制器失败")); } else if(EHOSTUNREACH == err_code || ENETUNREACH == err_code) { ACE_DEBUG((LM_ERROR,"无法连接设备主机")); node->SetState(KSGDeviceNode::dsError); } else { ACE_DEBUG((LM_ERROR,"连接主机未知错误![%d][%s]ip[%s]" ,err_code,ACE_OS::strerror(err_code),ip.c_str())); } // add by cash 释放 SOCKET // 2007-01-29 stream.close(); return -1; } // 设置 handler 为 BLOCK 的 // stream.disable(ACE_NONBLOCK); // 设置 linger 属性 struct linger lg; ACE_OS::memset(&lg,0,sizeof lg); lg.l_onoff = 1; // 3s lg.l_linger = 3; stream.set_option(SOL_SOCKET,SO_LINGER,&lg,sizeof lg); node->SetState(KSGDeviceNode::dsOnline); *handler = stream.get_handle(); return 0; }
void AIO_Output_Handler::open (ACE_HANDLE new_handle, ACE_Message_Block &) { ACE_SOCK_Stream peer (new_handle); int bufsiz = ACE_DEFAULT_MAX_SOCKET_BUFSIZ; peer.set_option (SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof bufsiz); reader_.open (*this, new_handle, 0, proactor ()); writer_.open (*this, new_handle, 0, proactor ()); ACE_Message_Block *mb = 0; ACE_NEW (mb, ACE_Message_Block (1)); reader_.read (*mb, 1); ACE_Sig_Action no_sigpipe ((ACE_SignalHandler) SIG_IGN); no_sigpipe.register_action (SIGPIPE, 0); can_write_ = 1; start_write (0); }
int ACE_Pipe::open (int buffer_size) { ACE_TRACE ("ACE_Pipe::open"); #if defined (ACE_LACKS_SOCKETPAIR) ACE_INET_Addr my_addr; ACE_SOCK_Acceptor acceptor; ACE_SOCK_Connector connector; ACE_SOCK_Stream reader; ACE_SOCK_Stream writer; int result = 0; # if defined (ACE_WIN32) ACE_INET_Addr local_any (static_cast<u_short> (0), ACE_LOCALHOST); # else ACE_Addr local_any = ACE_Addr::sap_any; # endif /* ACE_WIN32 */ // Bind listener to any port and then find out what the port was. if (acceptor.open (local_any) == -1 || acceptor.get_local_addr (my_addr) == -1) result = -1; else { ACE_INET_Addr sv_addr (my_addr.get_port_number (), ACE_LOCALHOST); // Establish a connection within the same process. if (connector.connect (writer, sv_addr) == -1) result = -1; else if (acceptor.accept (reader) == -1) { writer.close (); result = -1; } } // Close down the acceptor endpoint since we don't need it anymore. acceptor.close (); if (result == -1) return -1; this->handles_[0] = reader.get_handle (); this->handles_[1] = writer.get_handle (); # if !defined (ACE_LACKS_TCP_NODELAY) int one = 1; // Make sure that the TCP stack doesn't try to buffer small writes. // Since this communication is purely local to the host it doesn't // affect network performance. if (writer.set_option (ACE_IPPROTO_TCP, TCP_NODELAY, &one, sizeof one) == -1) { this->close (); return -1; } # endif /* ! ACE_LACKS_TCP_NODELAY */ # if defined (ACE_LACKS_SO_RCVBUF) && defined (ACE_LACKS_SO_SNDBUF) ACE_UNUSED_ARG (buffer_size); # endif # if !defined (ACE_LACKS_SO_RCVBUF) if (reader.set_option (SOL_SOCKET, SO_RCVBUF, reinterpret_cast <void *> (&buffer_size), sizeof (buffer_size)) == -1 && errno != ENOTSUP) { this->close (); return -1; } # endif /* !ACE_LACKS_SO_RCVBUF */ # if !defined (ACE_LACKS_SO_SNDBUF) if (writer.set_option (SOL_SOCKET, SO_SNDBUF, reinterpret_cast <void *> (&buffer_size), sizeof (buffer_size)) == -1 && errno != ENOTSUP) { this->close (); return -1; } # endif /* !ACE_LACKS_SO_SNDBUF */ #elif defined (ACE_HAS_STREAM_PIPES) || defined (__QNX__) ACE_UNUSED_ARG (buffer_size); if (ACE_OS::pipe (this->handles_) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("pipe")), -1); #if !defined(__QNX__) int arg = RMSGN; // Enable "msg no discard" mode, which ensures that record // boundaries are maintained when messages are sent and received. if (ACE_OS::ioctl (this->handles_[0], I_SRDOPT, (void *) arg) == -1 || ACE_OS::ioctl (this->handles_[1], I_SRDOPT, (void *) arg) == -1) { this->close (); ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ioctl")), -1); } #endif /* __QNX__ */ #else /* ! ACE_LACKS_SOCKETPAIR && ! ACE_HAS_STREAM_PIPES */ if (ACE_OS::socketpair (AF_UNIX, SOCK_STREAM, 0, this->handles_) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("socketpair")), -1); # if defined (ACE_LACKS_SO_SNDBUF) && defined (ACE_LACKS_SO_RCVBUF) ACE_UNUSED_ARG (buffer_size); # endif # if !defined (ACE_LACKS_SO_RCVBUF) if (ACE_OS::setsockopt (this->handles_[0], SOL_SOCKET, SO_RCVBUF, reinterpret_cast <const char *> (&buffer_size), sizeof (buffer_size)) == -1 && errno != ENOTSUP) { this->close (); return -1; } # endif # if !defined (ACE_LACKS_SO_SNDBUF) if (ACE_OS::setsockopt (this->handles_[1], SOL_SOCKET, SO_SNDBUF, reinterpret_cast <const char *> (&buffer_size), sizeof (buffer_size)) == -1 && errno != ENOTSUP) { this->close (); return -1; } # endif /* ! ACE_LACKS_SO_SNDBUF */ # if defined (ACE_OPENVMS) && !defined (ACE_LACKS_TCP_NODELAY) int one = 1; // OpenVMS implements socketpair(AF_UNIX...) by returning AF_INET sockets. // Since these are plagued by Nagle as any other INET socket we need to set // TCP_NODELAY on the write handle. if (ACE_OS::setsockopt (this->handles_[1], ACE_IPPROTO_TCP, TCP_NODELAY, reinterpret_cast <const char *> (&one), sizeof (one)) == -1) { this->close (); return -1; } # endif /* ACE_OPENVMS && !ACE_LACKS_TCP_NODELAY */ #endif /* ! ACE_LACKS_SOCKETPAIR && ! ACE_HAS_STREAM_PIPES */ // Point both the read and write HANDLES to the appropriate socket // HANDLEs. 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 */ }
// 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; }
void TestDriver::run_i() { ACE_Message_Block buffer (1000000); ACE_SOCK_Acceptor acceptor; if (acceptor.open(sub_addr_) == -1) { ACE_ERROR((LM_ERROR, "%p\n", "open")); throw TestException(); } ACE_SOCK_Stream peer; if (acceptor.accept(peer) == -1) { ACE_ERROR((LM_ERROR, "%p\n", "accept")); throw TestException(); } #if defined (ACE_DEFAULT_MAX_SOCKET_BUFSIZ) # if !defined (ACE_LACKS_SOCKET_BUFSIZ) // set connection options int snd_size = ACE_DEFAULT_MAX_SOCKET_BUFSIZ; int rcv_size = ACE_DEFAULT_MAX_SOCKET_BUFSIZ; int nodelay =1; if (peer.set_option (IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof (nodelay)) == -1) { ACE_ERROR((LM_ERROR, "(%P|%t) Subscriber failed to set TCP_NODELAY\n")); } if (peer.set_option (SOL_SOCKET, SO_SNDBUF, (void *) &snd_size, sizeof (snd_size)) == -1 && errno != ENOTSUP) { ACE_ERROR((LM_ERROR, "(%P|%t) TcpSubscriber failed to set the send buffer size to %d errno %m\n", snd_size)); } if (peer.set_option (SOL_SOCKET, SO_RCVBUF, (void *) &rcv_size, sizeof (int)) == -1 && errno != ENOTSUP) { ACE_ERROR((LM_ERROR, "(%P|%t) TcpSubscriber failed to set the receive buffer size to %d errno %m \n", rcv_size)); } # endif /* !ACE_LACKS_SOCKET_BUFSIZ */ #endif /* !ACE_DEFAULT_MAX_SOCKET_BUFSIZ */ ACE_DEBUG((LM_DEBUG, "(%T) Subscriber running.\n")); unsigned total_packets = num_packets_ + 500; int result; for (unsigned pkt_cnt = 0; pkt_cnt < total_packets; ++pkt_cnt) { if ((result = peer.recv(buffer.wr_ptr(), num_bytes_per_packet_)) == 0) { // The publisher has disconnected - check if this was unexpected. ACE_ERROR((LM_ERROR, "(%P|%t) Publisher disconnected at packet %d.\n", pkt_cnt)); throw TestException(); } else if (result < 0) { // Something bad happened ACE_ERROR((LM_ERROR, "(%P|%t) bad read\n")); throw TestException(); } else if ((unsigned) result != num_bytes_per_packet_) { // Something bad happened ACE_ERROR((LM_ERROR, "(%P|%t) read %d bytes but expected %d\n", result, num_bytes_per_packet_)); throw TestException(); } // only send 4 back result = 4; peer.send_n(buffer.wr_ptr(), result); } // Close the acceptor so that no more clients will be taken in. acceptor.close(); if (verbose_) { ACE_DEBUG((LM_DEBUG, "(%P|%t) Subscriber has completed.\n")); } }