UdpConnection.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * This file is part of workerman.
  4. *
  5. * Licensed under The MIT License
  6. * For full copyright and license information, please see the MIT-LICENSE.txt
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @author walkor<walkor@workerman.net>
  10. * @copyright walkor<walkor@workerman.net>
  11. * @link http://www.workerman.net/
  12. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Workerman\Connection;
  15. use Workerman\Protocols\ProtocolInterface;
  16. /**
  17. * UdpConnection.
  18. */
  19. class UdpConnection extends ConnectionInterface implements \JsonSerializable
  20. {
  21. /**
  22. * Application layer protocol.
  23. * The format is like this Workerman\\Protocols\\Http.
  24. *
  25. * @var ProtocolInterface
  26. */
  27. public $protocol = null;
  28. /**
  29. * Transport layer protocol.
  30. *
  31. * @var string
  32. */
  33. public $transport = 'udp';
  34. /**
  35. * Udp socket.
  36. *
  37. * @var resource
  38. */
  39. protected $socket = null;
  40. /**
  41. * Remote address.
  42. *
  43. * @var string
  44. */
  45. protected $remoteAddress = '';
  46. /**
  47. * Construct.
  48. *
  49. * @param resource $socket
  50. * @param string $remoteAddress
  51. */
  52. public function __construct($socket, $remoteAddress)
  53. {
  54. $this->socket = $socket;
  55. $this->remoteAddress = $remoteAddress;
  56. }
  57. /**
  58. * Sends data on the connection.
  59. *
  60. * @param string $sendBuffer
  61. * @param bool $raw
  62. * @return void|boolean
  63. */
  64. public function send($sendBuffer, $raw = false)
  65. {
  66. if (false === $raw && $this->protocol) {
  67. $parser = $this->protocol;
  68. $sendBuffer = $parser::encode($sendBuffer, $this);
  69. if ($sendBuffer === '') {
  70. return;
  71. }
  72. }
  73. return \strlen($sendBuffer) === \stream_socket_sendto($this->socket, $sendBuffer, 0, $this->isIpV6() ? '[' . $this->getRemoteIp() . ']:' . $this->getRemotePort() : $this->remoteAddress);
  74. }
  75. /**
  76. * Get remote IP.
  77. *
  78. * @return string
  79. */
  80. public function getRemoteIp()
  81. {
  82. $pos = \strrpos($this->remoteAddress, ':');
  83. if ($pos) {
  84. return \trim(\substr($this->remoteAddress, 0, $pos), '[]');
  85. }
  86. return '';
  87. }
  88. /**
  89. * Get remote port.
  90. *
  91. * @return int
  92. */
  93. public function getRemotePort()
  94. {
  95. if ($this->remoteAddress) {
  96. return (int)\substr(\strrchr($this->remoteAddress, ':'), 1);
  97. }
  98. return 0;
  99. }
  100. /**
  101. * Get remote address.
  102. *
  103. * @return string
  104. */
  105. public function getRemoteAddress()
  106. {
  107. return $this->remoteAddress;
  108. }
  109. /**
  110. * Get local IP.
  111. *
  112. * @return string
  113. */
  114. public function getLocalIp()
  115. {
  116. $address = $this->getLocalAddress();
  117. $pos = \strrpos($address, ':');
  118. if (!$pos) {
  119. return '';
  120. }
  121. return \substr($address, 0, $pos);
  122. }
  123. /**
  124. * Get local port.
  125. *
  126. * @return int
  127. */
  128. public function getLocalPort()
  129. {
  130. $address = $this->getLocalAddress();
  131. $pos = \strrpos($address, ':');
  132. if (!$pos) {
  133. return 0;
  134. }
  135. return (int)\substr(\strrchr($address, ':'), 1);
  136. }
  137. /**
  138. * Get local address.
  139. *
  140. * @return string
  141. */
  142. public function getLocalAddress()
  143. {
  144. return (string)@\stream_socket_get_name($this->socket, false);
  145. }
  146. /**
  147. * Is ipv4.
  148. *
  149. * @return bool.
  150. */
  151. public function isIpV4()
  152. {
  153. if ($this->transport === 'unix') {
  154. return false;
  155. }
  156. return \strpos($this->getRemoteIp(), ':') === false;
  157. }
  158. /**
  159. * Is ipv6.
  160. *
  161. * @return bool.
  162. */
  163. public function isIpV6()
  164. {
  165. if ($this->transport === 'unix') {
  166. return false;
  167. }
  168. return \strpos($this->getRemoteIp(), ':') !== false;
  169. }
  170. /**
  171. * Close connection.
  172. *
  173. * @param mixed $data
  174. * @param bool $raw
  175. * @return bool
  176. */
  177. public function close($data = null, $raw = false)
  178. {
  179. if ($data !== null) {
  180. $this->send($data, $raw);
  181. }
  182. $this->eventLoop = $this->errorHandler = null;
  183. return true;
  184. }
  185. /**
  186. * Get the real socket.
  187. *
  188. * @return resource
  189. */
  190. public function getSocket()
  191. {
  192. return $this->socket;
  193. }
  194. /**
  195. * Get the json_encode informattion.
  196. *
  197. * @return array
  198. */
  199. public function jsonSerialize()
  200. {
  201. return [
  202. 'transport' => $this->transport,
  203. 'getRemoteIp' => $this->getRemoteIp(),
  204. 'remotePort' => $this->getRemotePort(),
  205. 'getRemoteAddress' => $this->getRemoteAddress(),
  206. 'getLocalIp' => $this->getLocalIp(),
  207. 'getLocalPort' => $this->getLocalPort(),
  208. 'getLocalAddress' => $this->getLocalAddress(),
  209. 'isIpV4' => $this->isIpV4(),
  210. 'isIpV6' => $this->isIpV6(),
  211. ];
  212. }
  213. }