GUI/SoundGraphServer.cs
author StephaneLenclud
Sat, 09 Feb 2013 17:18:09 +0100
changeset 394 60a1e2b6ed71
child 395 df649224ba4d
permissions -rw-r--r--
At last we can output stuff on our display.
The whole thing is still quite broken though.
StephaneLenclud@394
     1
using System;
StephaneLenclud@394
     2
using Microsoft.Win32.SafeHandles;
StephaneLenclud@394
     3
using System.Text;
StephaneLenclud@394
     4
using System.Runtime.InteropServices;
StephaneLenclud@394
     5
using System.Threading;
StephaneLenclud@394
     6
using System.IO;
StephaneLenclud@394
     7
using System.Diagnostics;
StephaneLenclud@394
     8
StephaneLenclud@394
     9
namespace SoundGraph
StephaneLenclud@394
    10
{
StephaneLenclud@394
    11
    public class Server
StephaneLenclud@394
    12
    {
StephaneLenclud@394
    13
        [DllImport("kernel32.dll", SetLastError = true)]
StephaneLenclud@394
    14
        public static extern SafeFileHandle CreateNamedPipe(
StephaneLenclud@394
    15
           String pipeName,
StephaneLenclud@394
    16
           uint dwOpenMode,
StephaneLenclud@394
    17
           uint dwPipeMode,
StephaneLenclud@394
    18
           uint nMaxInstances,
StephaneLenclud@394
    19
           uint nOutBufferSize,
StephaneLenclud@394
    20
           uint nInBufferSize,
StephaneLenclud@394
    21
           uint nDefaultTimeOut,
StephaneLenclud@394
    22
           IntPtr lpSecurityAttributes);
StephaneLenclud@394
    23
StephaneLenclud@394
    24
        [DllImport("kernel32.dll", SetLastError = true)]
StephaneLenclud@394
    25
        public static extern int ConnectNamedPipe(
StephaneLenclud@394
    26
           SafeFileHandle hNamedPipe,
StephaneLenclud@394
    27
           IntPtr lpOverlapped);
StephaneLenclud@394
    28
StephaneLenclud@394
    29
        [DllImport("kernel32.dll", SetLastError = true)]
StephaneLenclud@394
    30
        public static extern int DisconnectNamedPipe(
StephaneLenclud@394
    31
           SafeFileHandle hNamedPipe);
StephaneLenclud@394
    32
StephaneLenclud@394
    33
        public const uint PIPE_ACCESS_DUPLEX = (0x00000003);
StephaneLenclud@394
    34
        public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
StephaneLenclud@394
    35
        public const uint PIPE_ACCESS_OUTBOUND = (0x00000002);
StephaneLenclud@394
    36
        public const uint PIPE_ACCESS_INBOUND = (0x00000001);
StephaneLenclud@394
    37
        public const uint PIPE_TYPE_BYTE = (0x00000000);
StephaneLenclud@394
    38
        public const uint PIPE_UNLIMITED_INSTANCES = 255;
StephaneLenclud@394
    39
          
StephaneLenclud@394
    40
        
StephaneLenclud@394
    41
StephaneLenclud@394
    42
StephaneLenclud@394
    43
        public const int BUFFER_SIZE = 256;
StephaneLenclud@394
    44
StephaneLenclud@394
    45
        //
StephaneLenclud@394
    46
        public string iPipeNameOutbound;
StephaneLenclud@394
    47
        Thread iThreadOutbound;
StephaneLenclud@394
    48
        SafeFileHandle iPipeOutbound;
StephaneLenclud@394
    49
        public FileStream iStreamOutbound;
StephaneLenclud@394
    50
        //
StephaneLenclud@394
    51
        public string iPipeNameInbound;
StephaneLenclud@394
    52
        Thread iThreadInbound;
StephaneLenclud@394
    53
        SafeFileHandle iPipeInbound;
StephaneLenclud@394
    54
        public FileStream iStreamInbound;
StephaneLenclud@394
    55
StephaneLenclud@394
    56
StephaneLenclud@394
    57
        public Server(string aPipeNameOutbound, string aPipeNameInbound)
StephaneLenclud@394
    58
        {
StephaneLenclud@394
    59
            iPipeNameOutbound = aPipeNameOutbound;
StephaneLenclud@394
    60
            iPipeNameInbound = aPipeNameInbound;
StephaneLenclud@394
    61
        }
StephaneLenclud@394
    62
       
StephaneLenclud@394
    63
        /**
StephaneLenclud@394
    64
         * Start our services.
StephaneLenclud@394
    65
         */
StephaneLenclud@394
    66
        public void Start()
StephaneLenclud@394
    67
        {
StephaneLenclud@394
    68
            //Start outbound thread to send messages
StephaneLenclud@394
    69
            this.iThreadOutbound = new Thread(new ThreadStart(ThreadOutbound));
StephaneLenclud@394
    70
            this.iThreadOutbound.Start();
StephaneLenclud@394
    71
            //Start inbound thread to receive messages
StephaneLenclud@394
    72
            this.iThreadInbound = new Thread(new ThreadStart(ThreadInbound));
StephaneLenclud@394
    73
            this.iThreadInbound.Start();
StephaneLenclud@394
    74
        }
StephaneLenclud@394
    75
StephaneLenclud@394
    76
        /**
StephaneLenclud@394
    77
         * Outbound thread is sending messages to our client.
StephaneLenclud@394
    78
         */
StephaneLenclud@394
    79
        private void ThreadOutbound()
StephaneLenclud@394
    80
        {
StephaneLenclud@394
    81
            
StephaneLenclud@394
    82
            //Create our outbound named pipe
StephaneLenclud@394
    83
            iPipeOutbound = CreateNamedPipe(this.iPipeNameOutbound, PIPE_ACCESS_OUTBOUND /*| FILE_FLAG_OVERLAPPED*/, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
StephaneLenclud@394
    84
StephaneLenclud@394
    85
            //Could not create named pipe
StephaneLenclud@394
    86
            if (iPipeOutbound.IsInvalid)
StephaneLenclud@394
    87
            {
StephaneLenclud@394
    88
                //TODO: error handling
StephaneLenclud@394
    89
                return;
StephaneLenclud@394
    90
            }
StephaneLenclud@394
    91
StephaneLenclud@394
    92
            //Will complete once our client connects
StephaneLenclud@394
    93
            int success = ConnectNamedPipe(iPipeOutbound, IntPtr.Zero);
StephaneLenclud@394
    94
StephaneLenclud@394
    95
            //could not connect client
StephaneLenclud@394
    96
            if (success == 0)
StephaneLenclud@394
    97
            {
StephaneLenclud@394
    98
                //TODO: error handling
StephaneLenclud@394
    99
                return;
StephaneLenclud@394
   100
            }
StephaneLenclud@394
   101
StephaneLenclud@394
   102
            //Client now connected create our stream
StephaneLenclud@394
   103
            iStreamOutbound = new FileStream(iPipeOutbound, FileAccess.Write, BUFFER_SIZE, false);
StephaneLenclud@394
   104
 
StephaneLenclud@394
   105
        }
StephaneLenclud@394
   106
StephaneLenclud@394
   107
        /**
StephaneLenclud@394
   108
         * Inbound thread is receiving messages from our client
StephaneLenclud@394
   109
         */
StephaneLenclud@394
   110
        private void ThreadInbound()
StephaneLenclud@394
   111
        {
StephaneLenclud@394
   112
            //Client client = (Client)clientObj;
StephaneLenclud@394
   113
            //clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
StephaneLenclud@394
   114
StephaneLenclud@394
   115
            iPipeInbound = CreateNamedPipe(this.iPipeNameInbound, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
StephaneLenclud@394
   116
StephaneLenclud@394
   117
            //could not create named pipe
StephaneLenclud@394
   118
            if (iPipeInbound.IsInvalid)
StephaneLenclud@394
   119
                return;
StephaneLenclud@394
   120
StephaneLenclud@394
   121
            //Will complete once a client connects
StephaneLenclud@394
   122
            int success = ConnectNamedPipe(iPipeInbound, IntPtr.Zero);
StephaneLenclud@394
   123
StephaneLenclud@394
   124
            //could not connect client
StephaneLenclud@394
   125
            if (success == 0)
StephaneLenclud@394
   126
                return;
StephaneLenclud@394
   127
StephaneLenclud@394
   128
            //Client now connected create our inbound stream
StephaneLenclud@394
   129
            iStreamInbound = new FileStream(iPipeInbound, FileAccess.Read, BUFFER_SIZE, false);
StephaneLenclud@394
   130
StephaneLenclud@394
   131
StephaneLenclud@394
   132
            byte[] buffer = null;
StephaneLenclud@394
   133
            ASCIIEncoding encoder = new ASCIIEncoding();
StephaneLenclud@394
   134
StephaneLenclud@394
   135
            while (true)
StephaneLenclud@394
   136
            {                
StephaneLenclud@394
   137
                int bytesRead = 0;
StephaneLenclud@394
   138
StephaneLenclud@394
   139
                try
StephaneLenclud@394
   140
                {
StephaneLenclud@394
   141
                    buffer = new byte[BUFFER_SIZE];
StephaneLenclud@394
   142
                    bytesRead = iStreamInbound.Read(buffer, 0, BUFFER_SIZE);
StephaneLenclud@394
   143
                }
StephaneLenclud@394
   144
                catch
StephaneLenclud@394
   145
                {
StephaneLenclud@394
   146
                    //read error has occurred
StephaneLenclud@394
   147
                    break;
StephaneLenclud@394
   148
                }
StephaneLenclud@394
   149
StephaneLenclud@394
   150
                //client has disconnected
StephaneLenclud@394
   151
                if (bytesRead == 0)
StephaneLenclud@394
   152
                    break;
StephaneLenclud@394
   153
StephaneLenclud@394
   154
                //fire message received event
StephaneLenclud@394
   155
                //if (this.MessageReceived != null)
StephaneLenclud@394
   156
                //    this.MessageReceived(clientse, encoder.GetString(buffer, 0, bytesRead));
StephaneLenclud@394
   157
StephaneLenclud@394
   158
                int ReadLength = 0;
StephaneLenclud@394
   159
                for (int i = 0; i < BUFFER_SIZE; i++)
StephaneLenclud@394
   160
                {
StephaneLenclud@394
   161
                    //if (buffer[i].ToString("x2") != "cc")
StephaneLenclud@394
   162
                    if (buffer[i] != 0)
StephaneLenclud@394
   163
                    {
StephaneLenclud@394
   164
                        ReadLength++;
StephaneLenclud@394
   165
                    }
StephaneLenclud@394
   166
                    else
StephaneLenclud@394
   167
                        break;
StephaneLenclud@394
   168
                }
StephaneLenclud@394
   169
                if (ReadLength > 0)
StephaneLenclud@394
   170
                {
StephaneLenclud@394
   171
                    byte[] Rc = new byte[ReadLength];
StephaneLenclud@394
   172
                    Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
StephaneLenclud@394
   173
StephaneLenclud@394
   174
                    Console.WriteLine(encoder.GetString(Rc, 0, ReadLength));
StephaneLenclud@394
   175
                    Trace.WriteLine("Received " + ReadLength + " Bytes: " + encoder.GetString(Rc, 0, ReadLength));
StephaneLenclud@394
   176
                    buffer.Initialize();
StephaneLenclud@394
   177
                }
StephaneLenclud@394
   178
               
StephaneLenclud@394
   179
            }
StephaneLenclud@394
   180
StephaneLenclud@394
   181
            //clean up resources
StephaneLenclud@394
   182
            iStreamInbound.Close();
StephaneLenclud@394
   183
            iPipeInbound.Close();            
StephaneLenclud@394
   184
        }
StephaneLenclud@394
   185
StephaneLenclud@394
   186
        /**
StephaneLenclud@394
   187
         * Send a message to our client.
StephaneLenclud@394
   188
         */
StephaneLenclud@394
   189
        public void SendMessage(string message)
StephaneLenclud@394
   190
        {
StephaneLenclud@394
   191
StephaneLenclud@394
   192
                ASCIIEncoding encoder = new ASCIIEncoding();
StephaneLenclud@394
   193
                byte[] messageBuffer = encoder.GetBytes(message);
StephaneLenclud@394
   194
StephaneLenclud@394
   195
                if (iStreamOutbound.CanWrite)
StephaneLenclud@394
   196
                {
StephaneLenclud@394
   197
                    iStreamOutbound.Write(messageBuffer, 0, messageBuffer.Length);
StephaneLenclud@394
   198
                    iStreamOutbound.Flush();
StephaneLenclud@394
   199
                }
StephaneLenclud@394
   200
StephaneLenclud@394
   201
StephaneLenclud@394
   202
        }
StephaneLenclud@394
   203
StephaneLenclud@394
   204
        /**
StephaneLenclud@394
   205
         * 
StephaneLenclud@394
   206
         */
StephaneLenclud@394
   207
        public void Stop()
StephaneLenclud@394
   208
        {
StephaneLenclud@394
   209
            //clean up resources
StephaneLenclud@394
   210
StephaneLenclud@394
   211
            DisconnectNamedPipe(this.iPipeOutbound);
StephaneLenclud@394
   212
StephaneLenclud@394
   213
            //TODO: more cleanup
StephaneLenclud@394
   214
            
StephaneLenclud@394
   215
StephaneLenclud@394
   216
            this.iThreadOutbound.Abort();
StephaneLenclud@394
   217
        }
StephaneLenclud@394
   218
StephaneLenclud@394
   219
    }
StephaneLenclud@394
   220
}