1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/GUI/SoundGraphServer.cs Sat Feb 09 17:18:09 2013 +0100
1.3 @@ -0,0 +1,220 @@
1.4 +using System;
1.5 +using Microsoft.Win32.SafeHandles;
1.6 +using System.Text;
1.7 +using System.Runtime.InteropServices;
1.8 +using System.Threading;
1.9 +using System.IO;
1.10 +using System.Diagnostics;
1.11 +
1.12 +namespace SoundGraph
1.13 +{
1.14 + public class Server
1.15 + {
1.16 + [DllImport("kernel32.dll", SetLastError = true)]
1.17 + public static extern SafeFileHandle CreateNamedPipe(
1.18 + String pipeName,
1.19 + uint dwOpenMode,
1.20 + uint dwPipeMode,
1.21 + uint nMaxInstances,
1.22 + uint nOutBufferSize,
1.23 + uint nInBufferSize,
1.24 + uint nDefaultTimeOut,
1.25 + IntPtr lpSecurityAttributes);
1.26 +
1.27 + [DllImport("kernel32.dll", SetLastError = true)]
1.28 + public static extern int ConnectNamedPipe(
1.29 + SafeFileHandle hNamedPipe,
1.30 + IntPtr lpOverlapped);
1.31 +
1.32 + [DllImport("kernel32.dll", SetLastError = true)]
1.33 + public static extern int DisconnectNamedPipe(
1.34 + SafeFileHandle hNamedPipe);
1.35 +
1.36 + public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
1.37 + public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
1.38 + public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
1.39 + public const uint PIPE_ACCESS_INBOUND = (0x00000001);
1.40 + public const uint PIPE_TYPE_BYTE = (0x00000000);
1.41 + public const uint PIPE_UNLIMITED_INSTANCES = 255;
1.42 +
1.43 +
1.44 +
1.45 +
1.46 + public const int BUFFER_SIZE = 256;
1.47 +
1.48 + //
1.49 + public string iPipeNameOutbound;
1.50 + Thread iThreadOutbound;
1.51 + SafeFileHandle iPipeOutbound;
1.52 + public FileStream iStreamOutbound;
1.53 + //
1.54 + public string iPipeNameInbound;
1.55 + Thread iThreadInbound;
1.56 + SafeFileHandle iPipeInbound;
1.57 + public FileStream iStreamInbound;
1.58 +
1.59 +
1.60 + public Server(string aPipeNameOutbound, string aPipeNameInbound)
1.61 + {
1.62 + iPipeNameOutbound = aPipeNameOutbound;
1.63 + iPipeNameInbound = aPipeNameInbound;
1.64 + }
1.65 +
1.66 + /**
1.67 + * Start our services.
1.68 + */
1.69 + public void Start()
1.70 + {
1.71 + //Start outbound thread to send messages
1.72 + this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
1.73 + this.iThreadOutbound.Start();
1.74 + //Start inbound thread to receive messages
1.75 + this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
1.76 + this.iThreadInbound.Start();
1.77 + }
1.78 +
1.79 + /**
1.80 + * Outbound thread is sending messages to our client.
1.81 + */
1.82 + private void ThreadOutbound()
1.83 + {
1.84 +
1.85 + //Create our outbound named pipe
1.86 + iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
1.87 +
1.88 + //Could not create named pipe
1.89 + if (iPipeOutbound.IsInvalid)
1.90 + {
1.91 + //TODO: error handling
1.92 + return;
1.93 + }
1.94 +
1.95 + //Will complete once our client connects
1.96 + int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
1.97 +
1.98 + //could not connect client
1.99 + if (success == 0)
1.100 + {
1.101 + //TODO: error handling
1.102 + return;
1.103 + }
1.104 +
1.105 + //Client now connected create our stream
1.106 + iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
1.107 +
1.108 + }
1.109 +
1.110 + /**
1.111 + * Inbound thread is receiving messages from our client
1.112 + */
1.113 + private void ThreadInbound()
1.114 + {
1.115 + //Client client = (Client)clientObj;
1.116 + //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
1.117 +
1.118 + iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
1.119 +
1.120 + //could not create named pipe
1.121 + if (iPipeInbound.IsInvalid)
1.122 + return;
1.123 +
1.124 + //Will complete once a client connects
1.125 + int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
1.126 +
1.127 + //could not connect client
1.128 + if (success == 0)
1.129 + return;
1.130 +
1.131 + //Client now connected create our inbound stream
1.132 + iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
1.133 +
1.134 +
1.135 + byte[] buffer = null;
1.136 + ASCIIEncoding encoder = new ASCIIEncoding();
1.137 +
1.138 + while (true)
1.139 + {
1.140 + int bytesRead = 0;
1.141 +
1.142 + try
1.143 + {
1.144 + buffer = new byte[BUFFER_SIZE];
1.145 + bytesRead = iStreamInbound.Read(buffer, 0, BUFFER_SIZE);
1.146 + }
1.147 + catch
1.148 + {
1.149 + //read error has occurred
1.150 + break;
1.151 + }
1.152 +
1.153 + //client has disconnected
1.154 + if (bytesRead == 0)
1.155 + break;
1.156 +
1.157 + //fire message received event
1.158 + //if (this.MessageReceived != null)
1.159 + // this.MessageReceived(clientse, encoder.GetString(buffer, 0, bytesRead));
1.160 +
1.161 + int ReadLength = 0;
1.162 + for (int i = 0; i < BUFFER_SIZE; i++)
1.163 + {
1.164 + //if (buffer[i].ToString("x2") != "cc")
1.165 + if (buffer[i] != 0)
1.166 + {
1.167 + ReadLength++;
1.168 + }
1.169 + else
1.170 + break;
1.171 + }
1.172 + if (ReadLength > 0)
1.173 + {
1.174 + byte[] Rc = new byte[ReadLength];
1.175 + Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
1.176 +
1.177 + Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
1.178 + Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
1.179 + buffer.Initialize();
1.180 + }
1.181 +
1.182 + }
1.183 +
1.184 + //clean up resources
1.185 + iStreamInbound.Close();
1.186 + iPipeInbound.Close();
1.187 + }
1.188 +
1.189 + /**
1.190 + * Send a message to our client.
1.191 + */
1.192 + public void SendMessage(string message)
1.193 + {
1.194 +
1.195 + ASCIIEncoding encoder = new ASCIIEncoding();
1.196 + byte[] messageBuffer = encoder.GetBytes(message);
1.197 +
1.198 + if (iStreamOutbound.CanWrite)
1.199 + {
1.200 + iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
1.201 + iStreamOutbound.Flush();
1.202 + }
1.203 +
1.204 +
1.205 + }
1.206 +
1.207 + /**
1.208 + *
1.209 + */
1.210 + public void Stop()
1.211 + {
1.212 + //clean up resources
1.213 +
1.214 + DisconnectNamedPipe(this.iPipeOutbound);
1.215 +
1.216 + //TODO: more cleanup
1.217 +
1.218 +
1.219 + this.iThreadOutbound.Abort();
1.220 + }
1.221 +
1.222 + }
1.223 +}