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