PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/M2k/udpif/udpservice.cc

https://github.com/pyloor/picklingtools
C++ | 1153 lines | 450 code | 208 blank | 495 comment | 44 complexity | 90cda583b5831a7afd60a0e984f5f79f MD5 | raw file
  1. // ///////////////////////////////////////////// Include Files
  2. #include <unistd.h>
  3. #include "udpservice.h"
  4. #include "m2sockete.h"
  5. // ///////////////////////////////////////////// Private Classes
  6. class UDPService_Private {
  7. public:
  8. // ///// Data Members
  9. // Use same socket for reading and writing.
  10. int_4 socket_fd;
  11. // ///// Methods
  12. UDPService_Private () :
  13. socket_fd(-1)
  14. { }
  15. void clearDescriptors ()
  16. {
  17. if (-1 != socket_fd) {
  18. UDPSocketLib::UDP_closeSocket(socket_fd);
  19. socket_fd = -1;
  20. }
  21. }
  22. };
  23. // ///////////////////////////////////////////// UDPService Methods
  24. //
  25. // Preconditions:
  26. //
  27. // Postconditions:
  28. //
  29. // Parameters:
  30. //
  31. // Description:
  32. //
  33. // Contructor
  34. //
  35. UDPService::UDPService () :
  36. M2ATTR_VAL(Host, ""),
  37. M2ATTR_VAL(Port, 0),
  38. M2ATTR_VAL(RemoteHost, ""),
  39. M2ATTR_VAL(RemotePort, 9141),
  40. port_(0),
  41. host_(""),
  42. isOpen_(false),
  43. remoteHost_(""),
  44. remotePort_(9141)
  45. {
  46. private_ = new UDPService_Private;
  47. addWakeUp_(socketNotice_, "socket");
  48. addWakeUp_(Port, "PortChange");
  49. addWakeUp_(RemoteHost, "RemoteHostChange");
  50. addWakeUp_(RemotePort, "RemotePortChange");
  51. Host.post(ThisHostName());
  52. SetRemoteHost (ThisHostName());
  53. remotePort_ = RemotePort.value();
  54. }
  55. //
  56. // Preconditions:
  57. //
  58. // Postconditions:
  59. //
  60. // Parameters:
  61. //
  62. // Description:
  63. //
  64. // Destructor
  65. //
  66. UDPService::~UDPService ()
  67. {
  68. closeNetworkPort_();
  69. delete private_;
  70. }
  71. //
  72. // Preconditions:
  73. //
  74. // Postconditions:
  75. // Returns: string containing local hostname or NULL string if failed.
  76. //
  77. // Parameters:
  78. //
  79. // Description:
  80. //
  81. // Utility routine for inheriting application to get local hostname
  82. // programmatically. Same value as UDPService::Host attribute.
  83. // Routine is used in UDPService to set value of Host attribute.
  84. //
  85. // Note: recommend UDPService::GetHost() function for this purpose
  86. // in inheriting apps.
  87. //
  88. string UDPService::ThisHostName ()
  89. {
  90. char hostname[1024];
  91. if (gethostname(hostname, 1024) < 0) {
  92. perror("gethostname");
  93. return string();
  94. } else
  95. return string(hostname);
  96. }
  97. //
  98. // Preconditions:
  99. //
  100. // Postconditions:
  101. // Returns: string containing value of UDPService::RemoteHost
  102. // attribute.
  103. //
  104. // Parameters:
  105. //
  106. // Description:
  107. //
  108. // Utility routine for inheriting application to get remote hostname
  109. // programmatically. Same value as UDPService::RemoteHost attribute.
  110. //
  111. string UDPService::GetRemoteHost () const
  112. {
  113. return remoteHost_;
  114. }
  115. //
  116. // Preconditions:
  117. //
  118. // Postconditions:
  119. // RemoteHost attribute is set to parameter value.
  120. //
  121. // Parameters:
  122. // const string& s IN; Remote hostname for UDPService::write()
  123. // function to send UDP datagrams to.
  124. //
  125. // Description:
  126. //
  127. // Utility routine for inheriting application to set
  128. // UDPService::RemoteHost attribute programmatically.
  129. //
  130. void UDPService::SetRemoteHost (const string& s)
  131. {
  132. remoteHost_ = s;
  133. RemoteHost.value(remoteHost_);
  134. }
  135. //
  136. // Preconditions:
  137. //
  138. // Postconditions:
  139. // RemotePort attribute is set to parameter value.
  140. //
  141. // Parameters:
  142. // int_4 n IN; Remote port number for UDPService::write()
  143. // function to send UDP datagrams to.
  144. //
  145. // Description:
  146. //
  147. // Utility routine for inheriting application to set
  148. // UDPService::RemotePort attribute programmatically.
  149. //
  150. void UDPService::SetRemotePort (int_4 n)
  151. {
  152. remotePort_ = n;
  153. RemotePort.value(remotePort_);
  154. }
  155. //
  156. // Preconditions:
  157. //
  158. // Postconditions:
  159. // Closes previously opened UDP socket port and re-opens new one
  160. // defined by parameter.
  161. //
  162. // Parameters:
  163. // int_4 n IN; Local (source) port number for receiving UDP
  164. // datagrams and through which sends are made over
  165. // network.
  166. //
  167. // Description:
  168. //
  169. // Utility routine for inheriting application to set
  170. // UDPService::Port attribute programmatically.
  171. //
  172. void UDPService::SetPort (int_4 n)
  173. {
  174. port_ = n;
  175. Port.value(port_);
  176. }
  177. //
  178. // Preconditions:
  179. //
  180. // Postconditions:
  181. // Returns value of UDPService::RemotePort Attribute.
  182. //
  183. // Parameters:
  184. //
  185. // Description:
  186. //
  187. // Utility routine for inheriting application to get
  188. // UDPService::RemotePort attribute programmatically.
  189. //
  190. int_4 UDPService::GetRemotePort () const
  191. {
  192. return remotePort_;
  193. }
  194. //
  195. // Preconditions:
  196. //
  197. // Postconditions:
  198. // Returns: string containing local hostname or NULL string if failed.
  199. //
  200. // Parameters:
  201. //
  202. // Description:
  203. //
  204. // Utility routine for inheriting application to get local hostname
  205. // programmatically. Same value as UDPService::Host attribute.
  206. //
  207. //
  208. string UDPService::GetHost () const
  209. {
  210. return host_;
  211. }
  212. //
  213. // Preconditions:
  214. //
  215. // Postconditions:
  216. // Returns: hostname & port identifier over which current UDP network
  217. // service is active. Returned string contains locale hostname
  218. // and port, delimited by a colon: <hostname:<port>, e.g.
  219. // "shaman:6667"
  220. //
  221. // Parameters:
  222. //
  223. // Description:
  224. //
  225. // Utility routine for inheriting application to get hostname:port
  226. // UDP service identifier. Intended for use in logging, error
  227. // reporting, etc.
  228. //
  229. //
  230. string UDPService::Identifier () const
  231. {
  232. return string(GetHost() + ":" + IntToString(GetPort()));
  233. }
  234. //
  235. // Preconditions:
  236. //
  237. // Postconditions:
  238. // Returns: remote hostname & port identifier to which UDPService::write()
  239. // will send UDP datagram messages. Returned string contains remote
  240. // hostname and port, delimited by a colon: <hostname:<port>, e.g.
  241. // "shaman:9141"
  242. //
  243. // Parameters:
  244. //
  245. // Description:
  246. //
  247. // Utility routine for inheriting application to get default destination
  248. // hostname:port identifier. Intended for use in logging, error
  249. // reporting, etc.
  250. //
  251. //
  252. string UDPService::RemoteIdentifier () const
  253. {
  254. return string(GetRemoteHost() + ":" + IntToString(GetRemotePort()));
  255. }
  256. int_4 UDPService::GetPort () const
  257. {
  258. return port_;
  259. }
  260. // Extend from Service-Primitive-Component
  261. void UDPService::preamble_ ()
  262. {
  263. Service::preamble_();
  264. //
  265. // Not here...
  266. //
  267. //openNetworkPort_();
  268. }
  269. // Extend from Service-Primitive-Component
  270. void UDPService::postamble_ ()
  271. {
  272. socketNotice_.disable();
  273. closeNetworkPort_();
  274. Service::postamble_();
  275. }
  276. // Extend from Service-Primitive-Component
  277. void UDPService::assembleMyself_ ()
  278. {
  279. Service::assembleMyself_();
  280. } // UDPService::AssembleMyself_
  281. // Extend from Service-Primitive-Component
  282. void UDPService::startMyself_ ()
  283. {
  284. Service::startMyself_();
  285. } // UDPService::startMyself_
  286. // Extend from Service-Primitive-Component
  287. void UDPService::startup_ ()
  288. {
  289. Service::startup_();
  290. port_ = Port.value();
  291. remotePort_ = RemotePort.value();
  292. remoteHost_ = RemoteHost.value();
  293. Host.post(ThisHostName());
  294. host_ = Host.value();
  295. //Port.value(port_);
  296. //RemoteHost.value(remoteHost_);
  297. //RemotePort.value(remotePort_);
  298. char hname[64];
  299. int_4 stat = UDPSocketLib::UDP_findHostByName(remoteHost_.c_str(),
  300. hname,
  301. sizeof(hname),
  302. &remoteAddr_);
  303. if (stat < 0) {
  304. log_.error("UDPService:: Hostname lookup FAILED; remoteHost_= <" +
  305. remoteHost_ + ">");
  306. validRemoteHost_ = false;
  307. } else
  308. validRemoteHost_ = true;
  309. remoteAddr_.sin_port = htons((u_short) remotePort_);
  310. stat = UDPSocketLib::UDP_findHostByName(host_.c_str(),
  311. hname,
  312. sizeof(hname),
  313. &localAddr_);
  314. if (stat < 0) {
  315. log_.error("UDPService:: Lookup FAILED for local host; host_= <" +
  316. host_ + ">");
  317. validLocalHost_ = false;
  318. } else
  319. validLocalHost_ = true;
  320. localAddr_.sin_port = htons((u_short) port_);
  321. openNetworkPort_();
  322. } // UDPService::startup_
  323. // Extend from Service-Primitive-Component
  324. void UDPService::stopMyself_ ()
  325. {
  326. closeNetworkPort_();
  327. Service::stopMyself_();
  328. }
  329. //
  330. // Preconditions:
  331. //
  332. // Postconditions:
  333. // Opened UDP network socket; load private socket file descriptor.
  334. //
  335. // Parameters:
  336. //
  337. // Description:
  338. //
  339. // Opens UDP network socket interface on port number specified by Port.
  340. //
  341. //
  342. void UDPService::openNetworkPort_ ()
  343. {
  344. //
  345. // Disable interrupts on socket
  346. //
  347. socketNotice_.disable();
  348. closeNetworkPort_();
  349. try {
  350. socketNotice_.clearDescriptors();
  351. int_4 try_port = port_;
  352. if (UDPSocketLib::UDP_openPort(&myServer_, try_port) == 0) {
  353. if (try_port != port_) {
  354. port_ = try_port;
  355. //Port.value(port_);
  356. }
  357. private_->socket_fd = UDPSocketLib::descriptorForServer(server_());
  358. //
  359. // Enable socket interrupts
  360. //
  361. socketNotice_.addDescriptor(UDPSocketLib::descriptorForServer(server_()));
  362. socketNotice_.enable();
  363. isOpen_ = true;
  364. log_.message("UDPService:: Opened UDP port: <" + Identifier() + ">; "+
  365. "Socket fd= <"+Stringize(UDPSocketLib::descriptorForServer(server_()))+">");
  366. }
  367. } catch (const SocketLowLevelEx& e) {
  368. log_.noteException(e);
  369. log_.warning("UDPService:: Unable to open UDP port: <" + Identifier() + ">");
  370. closeNetworkPort_();
  371. }
  372. } // UDPService::openNetworkPort_
  373. //
  374. // Preconditions:
  375. //
  376. // Postconditions:
  377. // Closed previously opened UDP network socket;
  378. //
  379. // Parameters:
  380. //
  381. // Description:
  382. //
  383. // Closes UDP network socket interface.
  384. //
  385. //
  386. void UDPService::closeNetworkPort_ ()
  387. {
  388. if (IsOpen()) {
  389. //cout<<"actualServerPort="<<UDPSocketLib::actualServerPort(server_())<<endl;
  390. // log_.message("UDPService:: Closing UDP port: <" + Identifier() + ">; "+
  391. // "Socket fd= <"+Stringize(UDPSocketLib::descriptorForServer(server_()))+">");
  392. socketNotice_.disable();
  393. socketNotice_.clearDescriptors();
  394. UDPSocketLib::destroyServer(myServer_);
  395. private_->clearDescriptors();
  396. isOpen_ = false;
  397. log_.message("UDPService:: Closed UDP port: <" + Identifier() + ">");
  398. }
  399. } // UDPService::closeNetworkPort_
  400. //
  401. // Preconditions:
  402. //
  403. // Postconditions:
  404. //
  405. // Parameters:
  406. //
  407. // Description:
  408. //
  409. // Interrupt service routine for processing attribute changes and
  410. // "socket" changes (UDP datagram arrival) from WakeOnSocket
  411. // Extended from Service inheritance.
  412. //
  413. //
  414. //
  415. bool UDPService::takeWakeUpCall_ (WakeCondition& waker)
  416. {
  417. string reason = waker.groupID();
  418. //
  419. // Not sure if i want it here...
  420. //
  421. //acknowledge_();
  422. //
  423. // Port attribute change
  424. //
  425. if (reason == "PortChange") {
  426. int_4 NewPort = Port.value();
  427. closeNetworkPort_();
  428. port_ = NewPort;
  429. log_.message("UDPService:: Changed Port attribute = <" +
  430. Stringize(port_) + ">");
  431. openNetworkPort_();
  432. if (port_ != Port.value()) {
  433. Port.value(port_);
  434. }
  435. acknowledge_();
  436. return true;
  437. }
  438. //
  439. // process socket wake condition
  440. // assume UDP datagram received...
  441. //
  442. else if (reason == "socket") { // some socket condition
  443. incomingData_();
  444. acknowledge_();
  445. return true;
  446. }
  447. //
  448. // process RemoteHost attribute change
  449. //
  450. else if (reason == "RemoteHostChange") {
  451. remoteHost_ = RemoteHost.value();
  452. log_.message ("UDPService:: Changed RemoteHost attribute = <"+remoteHost_+">");
  453. char hname[64];
  454. int_4 stat = UDPSocketLib::UDP_findHostByName(remoteHost_.c_str(),
  455. hname,
  456. sizeof(hname),
  457. &remoteAddr_);
  458. if (stat < 0) {
  459. log_.error("UDPService:: Hostname lookup FAILED; RemoteHost= <" +
  460. remoteHost_ + ">");
  461. validRemoteHost_ = false;
  462. } else
  463. validRemoteHost_ = true;
  464. acknowledge_();
  465. return true;
  466. }
  467. //
  468. // process RemotePort attribute change
  469. //
  470. else if (reason == "RemotePortChange") {
  471. remotePort_ = RemotePort.value();
  472. remoteAddr_.sin_port = htons((u_short) remotePort_);
  473. log_.message("UDPService:: Changed RemotePort attribute = <" +
  474. Stringize(remotePort_) + ">");
  475. acknowledge_();
  476. return true;
  477. } else {
  478. log_.warning("UDPService:: Unknown WakeCondition \"" + reason + "\"");
  479. }
  480. return true;
  481. }
  482. //
  483. // Preconditions:
  484. //
  485. // Postconditions:
  486. //
  487. // Parameters:
  488. //
  489. // Description:
  490. //
  491. // Called from Service::takeWakeUpCall() interrupt service routine for
  492. // processing WakeOnSocket "socket" changes. Assume UDP datagram arrival;
  493. // read buffer into application from TCP/IP (UDP) suite and process
  494. // application message/data.
  495. //
  496. // NOTE: This is a virtual function and is intended to be extended for
  497. // application level processing of data. This default just reads data and
  498. // prints hex to screen.
  499. //
  500. //
  501. //
  502. void UDPService::incomingData_ ()
  503. {
  504. int_u1 buffer[8192];
  505. int_4 length = sizeof(buffer);
  506. int_u4 flags (0);
  507. struct sockaddr_in client_addr;
  508. int_4 addrlen = sizeof(client_addr);
  509. int_4 NumBytes;
  510. try {
  511. //
  512. // recv()
  513. // recvfrom() returns; n > 0: # bytes read
  514. // n = 0: no msg/datagram avail (UNBLOCKED);
  515. // we do NOT use UNBLOCKED reads though..
  516. // or peer has done orderly shutdown (TCP only)
  517. // n < 0: "something wicked this way comes..."
  518. // sets errno; throws exception
  519. //
  520. NumBytes = UDPSocketLib::UDP_recvFrom (private_->socket_fd,
  521. (unsigned char *)buffer,
  522. length,
  523. flags,
  524. &client_addr,
  525. addrlen);
  526. if (NumBytes > 0) {
  527. char clientHost[64];
  528. int_4 len = sizeof(clientHost);
  529. UDPSocketLib::UDP_getHostByAddr (clientHost, len, &client_addr);
  530. string name (clientHost);
  531. log_.message("incomingData_::[UDP_recvFrom <clientAddr>] NumBytes= " +
  532. Stringize(NumBytes) + "; from <" + name + "(" +
  533. inet_ntoa(client_addr.sin_addr) + ")" + ":"+
  534. Stringize(ntohs(client_addr.sin_port)) + ">");
  535. }
  536. } catch (const SocketLowLevelEx& e) {
  537. log_.error ("UDPService::[incomingData_]- Read error; "+e.problem());
  538. }
  539. //
  540. // No data...
  541. //
  542. if (NumBytes == 0) {
  543. log_.message("UDPService::[incomingData_]- No Data");
  544. //closeNetworkPort_();
  545. }
  546. //
  547. // ERROR- UDP socket read error
  548. //
  549. else if (NumBytes < 0) {
  550. log_.error("UDPService::[incomingData_]- UDP socket read error; closing port...");
  551. closeNetworkPort_();
  552. }
  553. debugUDPOutput_ ((unsigned char *)buffer, NumBytes);
  554. } // UDPService::incomingData_
  555. void UDPService::debugUDPOutput_ (const unsigned char *buffer, const int_4 NumBytes)
  556. {
  557. int_4 cnt (0);
  558. while (cnt < NumBytes) {
  559. cout<<" //";
  560. for (Index i = 0; i < 20; i++) {
  561. if (cnt < NumBytes) {
  562. cout<<setw(2)<<setfill('0')<<hex<<(int_2)buffer[cnt];
  563. if (i != 19) cout<<" ";
  564. cnt++;
  565. } else {
  566. cout<<"**";
  567. if (i != 19) cout<<" ";
  568. }
  569. }
  570. cout<<"//"<<dec<<endl;
  571. } // while (cnt < NumBytes) {
  572. } // UDPService::debugUDPOutPut_
  573. //
  574. // Preconditions:
  575. //
  576. // Postconditions:
  577. //
  578. // Parameters:
  579. // const void* buf IN; buffer of data to send
  580. // const int_4 bytes IN; number bytes in buf to send
  581. //
  582. // Description:
  583. // Send data in buf over network using UDP from Host:Port to
  584. // destination defined by attributes RemoteHost:RemotePort
  585. //
  586. //
  587. int_4 UDPService::write (const void* buf,
  588. const int_4 bytes)
  589. {
  590. int_u4 flags (0);
  591. int_4 addrlen = sizeof(remoteAddr_);
  592. int_4 NumBytes = -1;
  593. if (validRemoteHost_) {
  594. try {
  595. //
  596. // sendTo() returns; n > 0: # bytes read
  597. // n = 0: no data written; EWOULDBLOCK or EAGAIN
  598. // from NONBLOCK socket setting, maybe..
  599. // n < 0: "something wicked this way comes..."
  600. // sets errno
  601. //
  602. NumBytes = UDPSocketLib::UDP_sendTo (private_->socket_fd,
  603. (unsigned char *)buf,
  604. bytes,
  605. flags,
  606. &remoteAddr_,
  607. addrlen);
  608. } catch (const SocketLowLevelEx& e) {
  609. log_.error ("UDPService::[write]- Failed UDP write to <"+ RemoteIdentifier() + ">");
  610. log_.error ("UDPService::[write]- " + e.problem());
  611. }
  612. } else {
  613. log_.warning("UDPService::[write]- Invalid RemoteHost; Unable to write to <" +
  614. RemoteIdentifier() + ">");
  615. }
  616. return NumBytes;
  617. } // UDPService::write
  618. //
  619. // Preconditions:
  620. //
  621. // Postconditions:
  622. //
  623. // Parameters:
  624. // const void* buf IN; buffer of data to send
  625. // const int_4 bytes IN; number bytes in buf to send
  626. // struct sockaddr_in* clientAddr, IN; destination address
  627. // const int_4 clientAddrLength IN; length of dest address struct
  628. //
  629. // Description:
  630. // Send data in buf over network using UDP from Host:Port to
  631. // destination defined by clientAddr
  632. //
  633. //
  634. int_4 UDPService::writeTo (const void* buf,
  635. const int_4 bytes,
  636. struct sockaddr_in* clientAddr,
  637. const int_4 clientAddrLength)
  638. {
  639. int_u4 flags (0);
  640. int_4 NumBytes = -1;
  641. try {
  642. //
  643. // sendTo() returns; n > 0: # bytes read
  644. // n = 0: no data written; EWOULDBLOCK or EAGAIN
  645. // from NONBLOCK socket setting, maybe..
  646. // n < 0: "something wicked this way comes..."
  647. // sets errno
  648. //
  649. NumBytes = UDPSocketLib::UDP_sendTo (private_->socket_fd,
  650. (unsigned char *)buf,
  651. bytes,
  652. flags,
  653. clientAddr,
  654. clientAddrLength);
  655. } catch (const SocketLowLevelEx& e) {
  656. char clientHost[64];
  657. int_4 len = sizeof(clientHost);
  658. UDPSocketLib::UDP_getHostByAddr (clientHost, len, clientAddr);
  659. string name (clientHost);
  660. log_.error ("UDPService::[writeTo]- Failed UDP write to <" +
  661. name + " (" +
  662. inet_ntoa(clientAddr->sin_addr) + "):"+
  663. Stringize(ntohs(clientAddr->sin_port)) + ">");
  664. log_.error ("UDPService::[writeTo]- " + e.problem());
  665. }
  666. return NumBytes;
  667. } // UDPService::writeTo
  668. //
  669. // Preconditions:
  670. //
  671. // Postconditions:
  672. //
  673. // Parameters:
  674. // const void* buf IN; buffer of data to send
  675. // const int_4 bytes IN; number bytes in buf to send
  676. // const string destHost IN; destination hostname
  677. // const int_4 destPort IN; destination port number
  678. //
  679. // Description:
  680. // Send data in buf over network using UDP from Host:Port to
  681. // destination defined parameters, destHost:destPort
  682. //
  683. //
  684. int_4 UDPService::writeTo (const void* buf,
  685. const int_4 bytes,
  686. const string destHost,
  687. const int_4 destPort)
  688. {
  689. int_u4 flags (0);
  690. int_4 NumBytes = -1;
  691. try {
  692. //
  693. // sendTo() returns; n > 0: # bytes read
  694. // n = 0: no data written; EWOULDBLOCK or EAGAIN
  695. // from NONBLOCK socket setting, maybe..
  696. // n < 0: "something wicked this way comes..."
  697. // sets errno
  698. //
  699. NumBytes = UDPSocketLib::UDP_sendTo (private_->socket_fd,
  700. (unsigned char *)buf,
  701. bytes,
  702. flags,
  703. destHost,
  704. destPort);
  705. } catch (const SocketLowLevelEx& e) {
  706. log_.error ("UDPService::[writeTo]- Failed UDP write to <" +
  707. destHost + ":" + Stringize(destPort) + ">");
  708. log_.error ("UDPService::[writeTo]- " + e.problem());
  709. }
  710. return NumBytes;
  711. } // UDPService::writeTo
  712. //
  713. // Preconditions:
  714. //
  715. // Postconditions:
  716. //
  717. // Parameters:
  718. // void* buf IN; buffer of data to send
  719. // const int_4 bytes IN; size of data buffer "buf"
  720. //
  721. // Description:
  722. // Get data in from UDP network interface SW and return in "buf"
  723. // array. Blind read of data received at opened Host:Port. No
  724. // sender or "source" info returned. Commonly used as just a
  725. // UDP port reader in apps that do not intend to send data, or
  726. // one that only send datagrams to a "well-known" port defined by
  727. // RemoteHost:RemotePort.
  728. //
  729. // returns; n > 0: # bytes read
  730. // n = 0: no msg avail (e.g. NONBLOCKING socket).
  731. // n < 0: "something wicked this way comes..."
  732. // sets errno; throws exception
  733. //
  734. //
  735. //
  736. int_4 UDPService::read (void* buf,
  737. const int_4 bytes)
  738. {
  739. int_u4 flags (0);
  740. struct sockaddr_in client_addr;
  741. int_4 addrlen = sizeof(client_addr);
  742. int_4 NumBytes = -1;
  743. try {
  744. //
  745. // recvfrom() returns; n > 0: # bytes read
  746. // n = 0: no msg avail or peer has done
  747. // orderly shutdown (TCP only)
  748. // n < 0: "something wicked this way comes..."
  749. // sets errno
  750. //
  751. NumBytes = UDPSocketLib::UDP_recvFrom (private_->socket_fd,
  752. (unsigned char *)buf,
  753. bytes,
  754. flags,
  755. &client_addr,
  756. addrlen);
  757. } catch (const SocketLowLevelEx& e) {
  758. log_.error ("UDPService::[read]- Read error; "+e.problem());
  759. }
  760. // ERROR- UDP socket read error
  761. if (NumBytes < 0) {
  762. log_.error("UDPService::[read] - Read error on UDP socket; Close port= <"+Stringize(port_)+"");
  763. closeNetworkPort_();
  764. //throw SocketLowLevelEx(identifier(), bytes);
  765. }
  766. return NumBytes;
  767. } // UDPService::read
  768. //
  769. // Preconditions:
  770. //
  771. // Postconditions:
  772. //
  773. // Parameters:
  774. // void* buf IN; buffer of data to send
  775. // const int_4 bytes IN; size of data buffer "buf"
  776. // const int_u4 flags IN; read flags consistent with
  777. // recvfrom() network IF call;
  778. // most commonly used would be MSG_PEEK
  779. //
  780. // Description:
  781. // Get data in from UDP network interface SW and return in "buf"
  782. // array. Blind read of data received at opened Host:Port. No
  783. // sender or "source" info returned. Commonly used as just a
  784. // UDP port reader in apps that do not intend to send data, or
  785. // one that only send datagrams to a "well-known" port defined by
  786. // RemoteHost:RemotePort.
  787. //
  788. // This is an overloaded variant to allow flag settings.
  789. //
  790. // returns; n > 0: # bytes read
  791. // n = 0: no msg avail (e.g. NONBLOCKING socket).
  792. // n < 0: "something wicked this way comes..."
  793. // sets errno; throws exception
  794. //
  795. //
  796. int_4 UDPService::read (void* buf,
  797. const int_4 bytes,
  798. const int_u4 flags)
  799. {
  800. struct sockaddr_in client_addr;
  801. int_4 addrlen = sizeof(client_addr);
  802. int_4 NumBytes = -1;
  803. try {
  804. //
  805. // recvfrom() returns; n > 0: # bytes read
  806. // n = 0: no msg avail or peer has done
  807. // orderly shutdown (TCP only)
  808. // n < 0: "something wicked this way comes..."
  809. // sets errno
  810. //
  811. NumBytes = UDPSocketLib::UDP_recvFrom (private_->socket_fd,
  812. (unsigned char *)buf,
  813. bytes,
  814. flags,
  815. &client_addr,
  816. addrlen);
  817. } catch (const SocketLowLevelEx& e) {
  818. log_.error ("UDPService::[read]- Read error; "+e.problem());
  819. }
  820. // ERROR- UDP socket read error
  821. if (NumBytes < 0) {
  822. log_.error("UDPService::[read] - Read error on UDP socket; Close port= <"+Stringize(port_)+"");
  823. closeNetworkPort_();
  824. //throw SocketLowLevelEx(identifier(), bytes);
  825. }
  826. return NumBytes;
  827. } // UDPService::read
  828. //
  829. // Preconditions:
  830. //
  831. // Postconditions:
  832. //
  833. // Parameters:
  834. // void* buf IN; buffer of data to send
  835. // const int_4 bytes IN; size of data buffer "buf"
  836. // const int_u4 flags IN; read flags consistent with
  837. // recvfrom() network IF call;
  838. // most commonly used would be MSG_PEEK
  839. // struct sockaddr_in* clientAddr OUT; network source address of sender
  840. // const int_4 clientAddrLength OUT; length of source address struct
  841. //
  842. // Description:
  843. // Get data in from UDP network interface SW and return in "buf"
  844. // array. Returns sender address info to application.
  845. //
  846. // This is an overloaded variant to return network "ready" sockaddr_in
  847. // structure so application can respond to sender, if desired.
  848. //
  849. // returns; n > 0: # bytes read
  850. // n = 0: no msg avail (e.g. NONBLOCKING socket).
  851. // n < 0: "something wicked this way comes..."
  852. // sets errno; throws exception
  853. //
  854. //
  855. int_4 UDPService::readFrom (void* buf,
  856. const int_4 bytes,
  857. const int_u4 flags,
  858. struct sockaddr_in* clientAddr,
  859. const int_4 clientAddrLength)
  860. {
  861. int_4 NumBytes = -1;
  862. try {
  863. //
  864. // recvfrom() returns; n > 0: # bytes read
  865. // n = 0: no msg avail or peer has done
  866. // orderly shutdown (TCP only)
  867. // n < 0: "something wicked this way comes..."
  868. // sets errno
  869. //
  870. NumBytes = UDPSocketLib::UDP_recvFrom (private_->socket_fd,
  871. (unsigned char *)buf,
  872. bytes,
  873. flags,
  874. clientAddr,
  875. clientAddrLength);
  876. } catch (const SocketLowLevelEx& e) {
  877. log_.error ("UDPService::[readFrom]- Read error; "+e.problem());
  878. }
  879. // ERROR- UDP socket read error
  880. if (NumBytes < 0) {
  881. log_.error("UDPService::[readFrom] - Read error on UDP socket; Close port= <"+Stringize(port_)+"");
  882. closeNetworkPort_();
  883. //throw SocketLowLevelEx(identifier(), bytes);
  884. }
  885. return NumBytes;
  886. } // UDPService::readFrom
  887. //
  888. // Preconditions:
  889. //
  890. // Postconditions:
  891. //
  892. // Parameters:
  893. // void* buf IN; buffer of data to send
  894. // const int_4 bytes IN; size of data buffer "buf"
  895. // const int_u4 flags IN; read flags consistent with
  896. // recvfrom() network IF call;
  897. // most commonly used would be MSG_PEEK
  898. // string &srcHost OUT; Hostname of sender
  899. // int_4 &srcPort OUT; Port number of sender
  900. //
  901. // Description:
  902. // Get data in from UDP network interface SW and return in "buf"
  903. // array. Returns sender hostname and port info to application.
  904. //
  905. // This is an overloaded variant to return srcHost:srcPort so
  906. // application can respond to sender, if desired.
  907. //
  908. // returns; n > 0: # bytes read
  909. // n = 0: no msg avail (e.g. NONBLOCKING socket).
  910. // n < 0: "something wicked this way comes..."
  911. // sets errno; throws exception
  912. //
  913. //
  914. int_4 UDPService::readFrom (void* buf,
  915. const int_4 bytes,
  916. const int_u4 flags,
  917. string &srcHost,
  918. int_4 &srcPort)
  919. {
  920. int_4 NumBytes = -1;
  921. try {
  922. //
  923. // recvfrom() returns; n > 0: # bytes read
  924. // n = 0: no msg avail or peer has done
  925. // orderly shutdown (TCP only)
  926. // n < 0: "something wicked this way comes..."
  927. // sets errno
  928. //
  929. NumBytes = UDPSocketLib::UDP_recvFrom (private_->socket_fd,
  930. (unsigned char *)buf,
  931. bytes,
  932. flags,
  933. srcHost,
  934. srcPort);
  935. } catch (const SocketLowLevelEx& e) {
  936. log_.error ("UDPService::[readFrom]- Read error; "+e.problem());
  937. }
  938. // ERROR- UDP socket read error
  939. if (NumBytes < 0) {
  940. log_.error("UDPService::[readFrom] - Read error on UDP socket; Close port= <"+Stringize(port_)+"");
  941. closeNetworkPort_();
  942. //throw SocketLowLevelEx(identifier(), bytes);
  943. }
  944. return NumBytes;
  945. } // UDPService::readFrom