44
55namespace Libuv {
66 public class TcpSocket {
7- static uv_buf_t alloc_cb ( IntPtr tcp , IntPtr size )
8- {
9- uv_buf_t buf ;
10- buf . data = Marshal . AllocHGlobal ( ( int ) size ) ;
11- #if __MonoCS__
12- buf . len = size ;
13- #else
14- buf . len = ( ulong ) size ;
15- #endif
16- return buf ;
17- }
18- static void unmanaged_read_cb ( IntPtr stream , IntPtr nread , uv_buf_t buf )
19- {
20- int size = ( int ) nread ;
21- if ( size < 0 ) {
22- if ( ( int ) buf . data != 0 )
23- Marshal . FreeHGlobal ( buf . data ) ;
24- IntPtr shutdown = Marshal . AllocHGlobal ( Sizes . ShutdownTSize ) ;
25- uv_shutdown ( shutdown , stream , after_shutdown ) ;
26- return ;
27- }
28- if ( size == 0 ) {
29- Marshal . FreeHGlobal ( buf . data ) ;
30- return ;
31- }
32- byte [ ] data = new byte [ size ] ;
33- Marshal . Copy ( buf . data , data , 0 , size ) ;
34- var handle = ( uv_handle_t ) Marshal . PtrToStructure ( stream , typeof ( uv_handle_t ) ) ;
35- var instance = GCHandle . FromIntPtr ( handle . data ) ;
36- var watcher_instance = ( TcpSocket ) instance . Target ;
37- watcher_instance . HandleRead ( data , size ) ;
38- Marshal . FreeHGlobal ( buf . data ) ;
39- }
7+ public UVStream Stream { get ; private set ; }
408 static void unmanaged_connect_cb ( IntPtr connection , int status )
419 {
42- if ( status != 0 ) {
43- throw new Exception ( uv_strerror ( uv_last_error ( ) ) ) ;
44- }
10+ Util . CheckError ( status ) ;
4511 var tmp = ( uv_connect_t ) Marshal . PtrToStructure ( connection , typeof ( uv_connect_t ) ) ;
4612 var handle = ( uv_handle_t ) Marshal . PtrToStructure ( tmp . handle , typeof ( uv_handle_t ) ) ;
4713 var instance = GCHandle . FromIntPtr ( handle . data ) ;
48- var watcher_instance = ( TcpSocket ) instance . Target ;
49- watcher_instance . HandleConnect ( ) ;
50- uv_read_start ( tmp . handle , alloc_cb , unmanaged_read_cb ) ;
51- }
52- static void after_shutdown ( IntPtr shutdown , int status )
53- {
54- // It'd be very difficult to get handle out of req
55- // So we'll store it in data & cast to uv_req_t
56- uv_shutdown_t tmp = ( uv_shutdown_t ) Marshal . PtrToStructure ( shutdown , typeof ( uv_shutdown_t ) ) ;
57- uv_close ( tmp . handle , on_close ) ;
58- Marshal . FreeHGlobal ( shutdown ) ;
14+ var socket_instance = ( TcpSocket ) instance . Target ;
15+ socket_instance . HandleConnect ( ) ;
16+ this . Stream = new Stream ( socket_instance . _handle ) ;
5917 }
6018 static void on_close ( IntPtr socket )
6119 {
@@ -66,63 +24,38 @@ static void on_close(IntPtr socket)
6624 watcher_instance . me . Free ( ) ;
6725 Marshal . FreeHGlobal ( socket ) ;
6826 }
69- static void after_write ( IntPtr write_req , int status )
70- {
71- var req = ( uv_req_t ) Marshal . PtrToStructure ( write_req , typeof ( uv_req_t ) ) ;
72- //var handle = GCHandle.FromIntPtr(req.data);
73- //handle.Free();
74- Marshal . FreeHGlobal ( write_req ) ;
75- }
7627 private IntPtr _handle ;
7728 public event Action < byte [ ] > OnData ;
7829 public event Action OnConnect ;
7930 private GCHandle me ;
8031 private IntPtr connection ;
8132 public TcpSocket ( )
8233 {
83- this . _handle = Marshal . AllocHGlobal ( Sizes . TcpTSize ) ;
84- uv_tcp_init ( this . _handle ) ;
34+ this . _handle = Marshal . AllocHGlobal ( Sizes . TcpT ) ;
35+ Util . CheckError ( uv_tcp_init ( this . _handle ) ) ;
8536 var handle = ( uv_handle_t ) Marshal . PtrToStructure ( this . _handle , typeof ( uv_handle_t ) ) ;
8637 this . me = GCHandle . Alloc ( this ) ;
8738 handle . data = GCHandle . ToIntPtr ( this . me ) ;
8839 Marshal . StructureToPtr ( handle , this . _handle , true ) ;
89- this . connection = Marshal . AllocHGlobal ( Sizes . ConnectTSize ) ;
40+ this . connection = Marshal . AllocHGlobal ( Sizes . ConnectT ) ;
9041 //can't attach anything to connect_t, it would get nulled
9142 }
9243 public void Connect ( IPEndPoint endpoint , Action OnConnect )
9344 {
9445 var info = uv_ip4_addr ( endpoint . Address . ToString ( ) , endpoint . Port ) ;
95- uv_tcp_connect ( this . connection , this . _handle , info , unmanaged_connect_cb ) ;
46+ Util . CheckError ( uv_tcp_connect ( this . connection , this . _handle , info , unmanaged_connect_cb ) ) ;
9647 this . OnConnect += OnConnect ;
9748 }
9849 public TcpSocket ( IntPtr ServerHandle )
9950 {
100- this . _handle = Marshal . AllocHGlobal ( Sizes . TcpTSize ) ;
101- uv_tcp_init ( this . _handle ) ;
102- uv_accept ( ServerHandle , this . _handle ) ;
51+ this . _handle = Marshal . AllocHGlobal ( Sizes . TcpT ) ;
52+ Util . CheckError ( uv_tcp_init ( this . _handle ) ) ;
53+ Util . CheckError ( uv_accept ( ServerHandle , this . _handle ) ) ;
10354 var handle = ( uv_handle_t ) Marshal . PtrToStructure ( this . _handle , typeof ( uv_handle_t ) ) ;
10455 this . me = GCHandle . Alloc ( this ) ;
10556 handle . data = GCHandle . ToIntPtr ( this . me ) ;
10657 Marshal . StructureToPtr ( handle , this . _handle , true ) ;
107- uv_read_start ( this . _handle , alloc_cb , unmanaged_read_cb ) ;
108- }
109- public void Write ( byte [ ] data , int length )
110- {
111- IntPtr write_request = Marshal . AllocHGlobal ( Sizes . WriteTSize ) ;
112- var dataptrhandle = GCHandle . Alloc ( data , GCHandleType . Pinned ) ;
113- // This is not being freed, which needs to be fixed
114- IntPtr dat = dataptrhandle . AddrOfPinnedObject ( ) ;
115- uv_buf_t [ ] buf = new uv_buf_t [ 1 ] ;
116- buf [ 0 ] . data = dat ;
117- #if __MonoCS__
118- buf [ 0 ] . len = ( IntPtr ) length ;
119- #else
120- buf [ 0 ] . len = ( ulong ) length ;
121- #endif
122- var req = ( uv_req_t ) Marshal . PtrToStructure ( write_request , typeof ( uv_req_t ) ) ;
123- req . data = dat ;
124- Marshal . StructureToPtr ( req , write_request , true ) ;
125- uv_write ( write_request , this . _handle , buf , 1 , after_write ) ;
58+ this . Stream = new Stream ( this . _handle ) ;
12659 }
12760 private void HandleConnect ( )
12861 {
@@ -131,13 +64,6 @@ private void HandleConnect()
13164 OnConnect ( ) ;
13265 }
13366 }
134- private void HandleRead ( byte [ ] data , int nread )
135- {
136- if ( OnData != null )
137- {
138- OnData ( data ) ;
139- }
140- }
14167 public void Close ( )
14268 {
14369 uv_close ( this . _handle , on_close ) ;
@@ -147,20 +73,10 @@ public void Close()
14773 [ DllImport ( "uv" ) ]
14874 internal static extern int uv_accept ( IntPtr socket , IntPtr stream ) ;
14975 [ DllImport ( "uv" ) ]
150- internal static extern int uv_read_start ( IntPtr stream , uv_alloc_cb alloc_cb , uv_read_cb read ) ;
151- [ DllImport ( "uv" ) ]
152- internal static extern int uv_write ( IntPtr req , IntPtr handle , uv_buf_t [ ] bufs , int bufcnt , uv_write_cb cb ) ;
153- [ DllImport ( "uv" ) ]
154- internal static extern int uv_shutdown ( IntPtr shutdown , IntPtr handle , uv_shutdown_cb cb ) ;
155- [ DllImport ( "uv" ) ]
15676 internal static extern int uv_close ( IntPtr handle , uv_close_cb cb ) ;
15777 [ DllImport ( "uv" ) ]
15878 internal static extern int uv_tcp_connect ( IntPtr connect , IntPtr tcp_handle , sockaddr_in address , uv_connect_cb cb ) ;
15979 [ DllImport ( "uv" ) ]
16080 internal static extern sockaddr_in uv_ip4_addr ( string ip , int port ) ;
161- [ DllImport ( "uv" ) ]
162- public static extern uv_err_t uv_last_error ( ) ;
163- [ DllImport ( "uv" ) ]
164- public static extern string uv_strerror ( uv_err_t err ) ;
16581 }
16682}
0 commit comments