From 1b4cbb32e049d3531551c065fcf272ce12b22d51 Mon Sep 17 00:00:00 2001 From: Joseph Henry Date: Wed, 1 Aug 2018 00:11:38 -0700 Subject: [PATCH] Added more example C# DLL client/server code --- .../ExampleWindowsCSharpApp/Program.cs | 99 ++++++++++++++++++- .../ExampleWindowsCSharpApp/libzt.cs | 68 ++++++++++--- 2 files changed, 148 insertions(+), 19 deletions(-) diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs index 275db4a..03fc748 100644 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs +++ b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/Program.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using System.Net; + using ZeroTier; namespace ExampleWindowsCSharpApp @@ -13,12 +16,102 @@ namespace ExampleWindowsCSharpApp static void Main(string[] args) { ulong nwid = 0xe4da7455b2b9ee6a; + Console.Write("waiting for libzt to come online...\n"); libzt.zts_startjoin("config_path", nwid); - Console.Write("started. now performing a socket call\n"); - int fd = libzt.zts_socket(2, 1, 0); + Console.Write("I am " + libzt.zts_get_node_id().ToString("X") +"\n"); + Console.Write("ZT ready\n"); + + int fd; + int err = 0; + bool clientMode = false; + + if ((fd = libzt.zts_socket(2, 1, 0)) < 0) + { + Console.Write("error creating socket\n"); + } + + // CLIENT + if (clientMode == true) + { + string remoteAddrStr = "172.28.221.116"; + Int16 remotePort = 2323; + // Convert managed address object to pointer for unmanaged code + libzt.SockAddrIn addr = new libzt.SockAddrIn(); + addr.Family = (byte)libzt.SockAddrFamily.Inet; + addr.Port = IPAddress.HostToNetworkOrder((Int16)remotePort); + addr.Addr = (uint)IPAddress.Parse(remoteAddrStr).Address; + IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn))); + Marshal.StructureToPtr(addr, addrPtr, false); + int addrlen = Marshal.SizeOf(addr); + + if ((err = libzt.zts_connect(fd, addrPtr, addrlen)) < 0) + { + Console.Write("error connecting to remote server\n"); + } + + // Send message + string msgStr = "Hello from C#!"; + byte[] msgBuf = Encoding.ASCII.GetBytes(msgStr); + int buflen = System.Text.ASCIIEncoding.ASCII.GetByteCount(msgStr); + + if ((err = libzt.zts_write(fd, msgBuf, buflen)) < 0) + { + Console.Write("error writing to remote server\n"); + } + + libzt.zts_close(fd); + Marshal.FreeHGlobal(addrPtr); + } + else // SERVER + { + string localAddrStr = "0.0.0.0"; + Int16 bindPort = 5050; + libzt.SockAddrIn addr = new libzt.SockAddrIn(); + addr.Family = (byte)libzt.SockAddrFamily.Inet; + addr.Port = IPAddress.HostToNetworkOrder((Int16)bindPort); + addr.Addr = (uint)IPAddress.Parse(localAddrStr).Address; + IntPtr addrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libzt.SockAddrIn))); + Marshal.StructureToPtr(addr, addrPtr, false); + int addrlen = Marshal.SizeOf(addr); + + if ((err = libzt.zts_bind(fd, addrPtr, addrlen)) < 0) + { + Console.Write("error binding to local port\n"); + } + if ((err = libzt.zts_listen(fd, 1)) < 0) + { + Console.Write("error putting socket in listening state\n"); + } + int accfd; + Console.Write("waiting to accept connection...\n"); + if ((accfd = libzt.zts_accept(fd, IntPtr.Zero, IntPtr.Zero)) < 0) + { + Console.Write("error accepting incoming connection\n"); + } + Console.Write("accepted connection!\n"); + + + // Read message + byte[] msgBuf = new byte[32]; + int buflen = 32; + Console.Write("reading from client...\n"); + if ((err = libzt.zts_read(accfd, msgBuf, buflen)) < 0) + { + Console.Write("error reading from remote client\n"); + } + Console.Write("read " + err + " bytes from client\n"); + string msgStr = System.Text.Encoding.UTF8.GetString(msgBuf, 0, msgBuf.Length); + Console.Write("msg from client = " + msgStr + "\n"); + + libzt.zts_close(fd); + libzt.zts_close(accfd); + Marshal.FreeHGlobal(addrPtr); + } + Console.Write("fd=" + fd); - // zts_connect(), zts_bind(), etc... + Console.Write("wrote=" + err); + libzt.zts_stop(); } } diff --git a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs index b3e7510..fe43c5e 100644 --- a/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs +++ b/examples/csharp/ExampleWindowsCSharpApp/ExampleWindowsCSharpApp/libzt.cs @@ -10,6 +10,42 @@ namespace ZeroTier { static class libzt { + public enum SockAddrFamily + { + Inet = 2, + Inet6 = 10 + } + + [StructLayout(LayoutKind.Sequential)] + public struct SockAddr + { + public ushort Family; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] + public byte[] Data; + }; + + [StructLayout(LayoutKind.Sequential)] + public struct SockAddrIn + { + byte len; // unique to lwIP + public byte Family; + public Int16 Port; + public uint Addr; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] Zero; + } + + [StructLayout(LayoutKind.Sequential)] + public struct SockAddrIn6 + { + public ushort Family; + public ushort Port; + public uint FlowInfo; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[] Addr; + public uint ScopeId; + }; + /****************************************************************************/ /* ZeroTier Service Controls */ /****************************************************************************/ @@ -33,7 +69,7 @@ namespace ZeroTier public static extern void zts_get_homepath(string homePath, int len); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_get_id(string nodeId); + public static extern Int64 zts_get_node_id(); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int zts_running(); @@ -42,13 +78,13 @@ namespace ZeroTier public static extern int zts_has_address(ulong nwid); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_address(ulong nwid, System.IntPtr addr, int addrlen); + public static extern void zts_get_address(ulong nwid, IntPtr addr, int addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_6plane_addr(System.IntPtr addr, string nwid, string nodeId); + public static extern void zts_get_6plane_addr(IntPtr addr, string nwid, string nodeId); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern void zts_get_rfc4193_addr(System.IntPtr addr, string nwid, string nodeId); + public static extern void zts_get_rfc4193_addr(IntPtr addr, string nwid, string nodeId); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern long zts_get_peer_count(); @@ -64,16 +100,16 @@ namespace ZeroTier public static extern int zts_socket(int socket_family, int socket_type, int protocol); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_connect(int fd, System.IntPtr addr, int addrlen); + public static extern int zts_connect(int fd, IntPtr addr, int addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_bind(int fd, System.IntPtr addr, int addrlen); + public static extern int zts_bind(int fd, IntPtr addr, int addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int zts_listen(int fd, int backlog); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_accept(int fd, System.IntPtr addr, IntPtr addrlen); + public static extern int zts_accept(int fd, IntPtr addr, IntPtr addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int zts_setsockopt(int fd, int level, int optname, IntPtr optval, int optlen); @@ -82,7 +118,7 @@ namespace ZeroTier public static extern int zts_getsockopt(int fd, int level, int optname, IntPtr optval, IntPtr optlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_getsockname(int fd, System.IntPtr addr, IntPtr addrlen); + public static extern int zts_getsockname(int fd, IntPtr addr, IntPtr addrlen); /* [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] @@ -111,28 +147,28 @@ namespace ZeroTier public static extern int zts_ioctl(int fd, ulong request, IntPtr argp); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_send(int fd, IntPtr buf, int len, int flags); + public static extern int zts_send(int fd, byte[] buf, int len, int flags); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_sendto(int fd, IntPtr buf, int len, int flags, System.IntPtr addr, int addrlen); + public static extern int zts_sendto(int fd, byte[] buf, int len, int flags, IntPtr addr, int addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_sendmsg(int fd, IntPtr msg, int flags); + public static extern int zts_sendmsg(int fd, byte[] msg, int flags); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recv(int fd, IntPtr buf, int len, int flags); + public static extern int zts_recv(int fd, byte[] buf, int len, int flags); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recvfrom(int fd, IntPtr buf, int len, int flags, System.IntPtr addr, IntPtr addrlen); + public static extern int zts_recvfrom(int fd, byte[] buf, int len, int flags, IntPtr addr, IntPtr addrlen); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_recvmsg(int fd, IntPtr msg, int flags); + public static extern int zts_recvmsg(int fd, byte[] msg, int flags); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_read(int fd, IntPtr buf, int len); + public static extern int zts_read(int fd, byte[] buf, int len); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int zts_write(int fd, IntPtr buf, int len); + public static extern int zts_write(int fd, byte[] buf, int len); [DllImport("libzt.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int zts_shutdown(int fd, int how);