socket.monkey2 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. Namespace std.socket
  2. #If __TARGET__="windows"
  3. #Import "<libWs2_32.a>"
  4. #Endif
  5. #Import "native/socket.cpp"
  6. #Import "native/socket.h"
  7. Extern
  8. #rem monkeydoc @hidden
  9. #end
  10. Function socket_connect:Int( hostname:String,service:String,type:Int )="bbSocket::connect"
  11. #rem monkeydoc @hidden
  12. #end
  13. Function socket_bind:Int( service:String )="bbSocket::bind"
  14. #rem monkeydoc @hidden
  15. #end
  16. Function socket_listen:Int( service:String,queue:Int )="bbSocket::listen"
  17. #rem monkeydoc @hidden
  18. #end
  19. Function socket_accept:Int( socket:Int )="bbSocket::accept"
  20. #rem monkeydoc @hidden
  21. #end
  22. Function socket_close( socket:Int )="bbSocket::close"
  23. #rem monkeydoc @hidden
  24. #end
  25. Function socket_send:Int( socket:Int,data:Void Ptr,size:Int )="bbSocket::send"
  26. #rem monkeydoc @hidden
  27. #end
  28. Function socket_recv:Int( socket:Int,data:Void Ptr,size:Int )="bbSocket::recv"
  29. #rem monkeydoc @hidden
  30. #end
  31. Function socket_sendto:Int( socket:Int,data:Void Ptr,size:Int,addr:Void ptr,addrlen:Int )="bbSocket::sendto"
  32. #rem monkeydoc @hidden
  33. #end
  34. Function socket_recvfrom:Int( socket:Int,data:Void Ptr,size:Int,addr:Void ptr,addrlen:Int Ptr )="bbSocket::recvfrom"
  35. #rem monkeydoc @hidden
  36. #end
  37. Function socket_setopt( socket:Int,opt:String,value:Int )="bbSocket::setopt"
  38. #rem monkeydoc @hidden
  39. #end
  40. Function socket_getopt:Int( socket:Int,opt:String )="bbSocket::getopt"
  41. #rem monkeydoc @hidden
  42. #end
  43. Function socket_cansend:Int( socket:Int )="bbSocket::cansend"
  44. #rem monkeydoc @hidden
  45. #end
  46. Function socket_canrecv:Int( socket:Int )="bbSocket::canrecv"
  47. #rem monkeydoc @hidden
  48. #end
  49. Function socket_getsockaddr:Int( socket:Int,addr:Void Ptr,addrlen:Int Ptr )="bbSocket::getsockaddr"
  50. #rem monkeydoc @hidden
  51. #end
  52. Function socket_getpeeraddr:Int( socket:Int,addr:Void Ptr,addrlen:Int Ptr )="bbSocket::getpeeraddr"
  53. #rem monkeydoc @hidden
  54. #end
  55. Function socket_sockaddrname:Int( addr:Void Ptr,addrlen:Int,host:libc.char_t Ptr,service:libc.char_t Ptr )="bbSocket::sockaddrname"
  56. Public
  57. Enum SocketType
  58. Stream=0
  59. Datagram=1
  60. End
  61. Class SocketAddress
  62. Property Host:String()
  63. Validate()
  64. Return _host
  65. End
  66. Property Service:String()
  67. Validate()
  68. Return _service
  69. End
  70. Method To:String()
  71. Return Host+":"+Service
  72. End
  73. Private
  74. Field _addr:=New Byte[128]
  75. Field _addrlen:Int=0
  76. Field _dirty:Bool=False
  77. Field _host:String=""
  78. Field _service:String=""
  79. Method Validate()
  80. If Not _dirty Return
  81. Local host:=New libc.char_t[1024]
  82. Local service:=New libc.char_t[80]
  83. If socket_sockaddrname( _addr.Data,_addrlen,host.Data,service.Data )>=0
  84. _host=String.FromCString( host.Data )
  85. _service=String.FromCString( service.Data )
  86. Else
  87. _host=""
  88. _service=""
  89. Endif
  90. _dirty=False
  91. End
  92. Property Addr:Void Ptr()
  93. Return _addr.Data
  94. End
  95. Property Addrlen:Int()
  96. Return _addrlen
  97. End
  98. Method Update( addrlen:Int )
  99. _addrlen=addrlen
  100. If _addrlen
  101. _dirty=True
  102. Return
  103. Endif
  104. _host=""
  105. _service=""
  106. _dirty=False
  107. End
  108. End
  109. Class Socket
  110. #rem Not on Windows...
  111. #rem monkeydoc The number of bytes that be sent to the socket without it blocking.
  112. #end
  113. Property CanSend:Int()
  114. If _socket=-1 Return 0
  115. Return socket_cansend( _socket )
  116. End
  117. #end
  118. #rem monkeydoc True if socket has been closed
  119. #end
  120. Property Closed:Bool()
  121. Return _socket=-1
  122. End
  123. #rem monkeydoc The number of bytes that can be received from the socket without blocking.
  124. #end
  125. Property CanReceive:Int()
  126. If _socket=-1 Return 0
  127. Return socket_canrecv( _socket )
  128. End
  129. #rem monkeydoc The address of the socket.
  130. #end
  131. Property Address:SocketAddress()
  132. If _socket=-1 Return Null
  133. If Not _addr
  134. Local addrlen:Int=128
  135. _addr=New SocketAddress
  136. Local n:=socket_getsockaddr( _socket,_addr.Addr,Varptr addrlen )
  137. _addr.Update( n>=0 ? addrlen Else 0 )
  138. Endif
  139. Return _addr
  140. End
  141. #rem monkeydoc The address of the socket peer.
  142. #end
  143. Property PeerAddress:SocketAddress()
  144. If _socket=-1 Return Null
  145. If Not _peer
  146. Local addrlen:Int=128
  147. _peer=New SocketAddress
  148. Local n:=socket_getpeeraddr( _socket,_peer.Addr,Varptr addrlen )
  149. _peer.Update( n>=0 ? addrlen Else 0 )
  150. Endif
  151. Return _peer
  152. End
  153. #rem monkeydoc Accepts a new incoming connection on a listening socket.
  154. Returns null if there was an error, otherwise blocks until an incoming connection has been made.
  155. @return new incomnig connection or null if there was an error.
  156. #end
  157. Method Accept:Socket()
  158. If _socket=-1 Return Null
  159. Local socket:=socket_accept( _socket )
  160. If socket=-1 Return Null
  161. Return New Socket( socket )
  162. End
  163. #rem monkeydoc Closes a socket.
  164. Once closed, a socket should not be used anymore.
  165. #end
  166. Method Close()
  167. If _socket=-1 Return
  168. socket_close( _socket )
  169. _socket=-1
  170. _addr=Null
  171. _peer=null
  172. End
  173. #rem monkeydoc Sends data on a connected socket.
  174. Writes `size` bytes to the socket.
  175. Returns the number of bytes actually written.
  176. Can return less than `sizet` if the socket has been closed by the peer or if an error occured.
  177. @param buf The memory buffer to write data from.
  178. @param size The number of bytes to write to the socket.
  179. @return The number of bytes actually written.
  180. #end
  181. Method Send:Int( data:Void Ptr,size:Int )
  182. If _socket=-1 Return 0
  183. Return socket_send( _socket,data,size )
  184. End
  185. Method SendTo:Int( data:Void Ptr,size:Int,address:SocketAddress )
  186. If _socket=-1 Return 0
  187. DebugAssert( address.Addrlen,"SocketAddress is invalid" )
  188. Return socket_sendto( _socket,data,size,address.Addr,address.Addrlen )
  189. End
  190. #rem monkeydoc Receives data on a connected socket.
  191. Reads at most `size` bytes from the socket.
  192. Returns 0 if the socket has been closed by the peer.
  193. Can return less than `size`, in which case you may have to read again if you know there's more data coming.
  194. @param buf The memory buffer to read data into.
  195. @param size The number of bytes to read from the socket.
  196. @return The number of bytes actually read.
  197. #end
  198. Method Receive:Int( data:Void Ptr,size:Int )
  199. If _socket=-1 Return 0
  200. Return socket_recv( _socket,data,size )
  201. End
  202. Method ReceiveFrom:Int( data:Void Ptr,size:Int,address:SocketAddress )
  203. If _socket=-1 Return 0
  204. Local addrlen:Int=128
  205. Local n:=socket_recvfrom( _socket,data,size,address.Addr,Varptr addrlen )
  206. address.Update( n>=0 ? addrlen Else 0 )
  207. Return n
  208. End
  209. #rem monkeydoc Sets a socket option.
  210. Currently, only "TCP_NODELAY" is supported, which should be 1 to enable, 0 to disable.
  211. #end
  212. Method SetOption( opt:String,value:Int )
  213. If _socket=-1 Return
  214. socket_setopt( _socket,opt,value )
  215. End
  216. #rem monkeydoc Gets a socket option.
  217. #end
  218. Method GetOption:Int( opt:String )
  219. If _socket=-1 Return -1
  220. Return socket_getopt( _socket,opt )
  221. End
  222. #rem monkeydoc Creates a connected socket.
  223. Attempts to connect to the host at `hostname` and service at `service` and returns a new connected socket if successful.
  224. Returns a closed socket upon failue.
  225. @return A new socket.
  226. #end
  227. Function Connect:Socket( hostname:String,service:String,type:SocketType=SocketType.Stream )
  228. Local socket:=socket_connect( hostname,service,type )
  229. If socket=-1 Return Null
  230. Return New Socket( socket )
  231. End
  232. #rem monkeydoc Creates a server socket.
  233. Returns a new server socket listening at `service` if successful.
  234. Returns a closed socket upon failure.
  235. @return A new socket.
  236. #end
  237. Function Bind:Socket( service:String )
  238. Local socket:=socket_bind( service )
  239. If socket=-1 Return Null
  240. Return New Socket( socket )
  241. End
  242. #rem monkeydoc Creates a server socket and listens on it.
  243. Returns a new server socket listening at `service` if successful.
  244. Returns a closed socket upon failure.
  245. @return A new socket.
  246. #end
  247. Function Listen:Socket( service:String,queue:Int=128 )
  248. Local socket:=socket_listen( service,queue )
  249. If socket=-1 Return Null
  250. Return New Socket( socket )
  251. End
  252. Private
  253. Field _socket:Int=-1
  254. Field _addr:SocketAddress
  255. Field _peer:SocketAddress
  256. Method New( socket:Int )
  257. _socket=socket
  258. End
  259. End