Advertisement
Guest User

pipe client example

a guest
Jan 25th, 2017
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 3.19 KB | None | 0 0
  1. #///////////////////////// client.nim /////////////////
  2. #
  3. #Client Program for Win32 Named Pipes Example.
  4. #Based on cpp example by Peter R. Bloomfield.
  5. #
  6. #For an explanation of the code, see the associated blog post:
  7. #http://avidinsight.uk/2012/03/introduction-to-win32-named-pipes-cpp/
  8. #https://github.com/avidinsight/win32-named-pipes-example/blob/master/src/client.cpp
  9. #
  10. #This code is made freely available under the MIT open source license
  11. #(see accompanying LICENSE file for details).
  12. #It is intended only for educational purposes. and is provide as-is with no
  13. #guarantee about its reliability, correctness, or suitability for any purpose.
  14. #
  15. #
  16. #TEST INSTRUCTIONS:
  17. #
  18. #Run the accompanying server program first.
  19. #Before closing it, run this client program.
  20. #
  21.  
  22. import winlean, os
  23. import message
  24. const
  25.   pipeHeaderName = r"\\.\pipe\mypipe"  # must match name in server.nim
  26.  
  27. const
  28.   DEFAULT_PIPE_SIZE = 65536'i32
  29.   FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000'i32
  30.   PIPE_WAIT = 0x00000000'i32
  31.   PIPE_TYPE_BYTE = 0x00000000'i32
  32.   PIPE_READMODE_BYTE = 0x00000000'i32
  33.   ERROR_PIPE_CONNECTED = 535
  34.   ERROR_PIPE_BUSY = 231
  35.   ERROR_BROKEN_PIPE = 109
  36.   ERROR_PIPE_NOT_CONNECTED = 233
  37.  
  38. var pipe:Handle
  39.  
  40. proc connectPipe*() =
  41.   echo "Connecting to pipe..."
  42.   # Open the named pipe
  43.   var pipeName = newWideCString(pipeHeaderName)
  44.   var sa = SECURITY_ATTRIBUTES(nLength: sizeof(SECURITY_ATTRIBUTES).cint,
  45.                                lpSecurityDescriptor: nil, bInheritHandle: 1)
  46.   pipe = createFileW(pipeName, GENERIC_READ, # only need read access
  47.                      0, sa.addr, OPEN_EXISTING,
  48.                      FILE_ATTRIBUTE_NORMAL, 0)
  49.  
  50.   if pipe == INVALID_HANDLE_VALUE:
  51.     echo "Failed to connect to pipe."
  52.     let err = osLastError()
  53.     if err.int32 != ERROR_PIPE_BUSY:
  54.       raiseOsError(err)
  55.  
  56.  
  57. proc recvMessage*(buffer: ptr Message ):bool =
  58.   #echo "Reading data from pipe..."
  59.   result = false
  60.   var
  61.     msglen = 0.int32
  62.     res = 0.int32
  63.   try:
  64.     discard pipe.peekNamedPipe(cast[pointer](buffer),sizeof(Message).int32, msglen.addr) # not blocked
  65.   except:
  66.     return false
  67.   if msglen == 0:
  68.     return false
  69.  
  70.   var numBytesRead:int32  = 0
  71.   try:
  72.     res  = readFile(pipe, cast[pointer](buffer), # the data from the pipe will be put here
  73.                     sizeof(Message).int32,
  74.                     numBytesRead.addr, # this will store number of bytes actually read
  75.                     nil)
  76.   except:
  77.     return false
  78.   if res > 0:
  79.     # echo "Number of bytes read: ", numBytesRead
  80.     # echo "Message: ", buffer[]
  81.     return true
  82.   else:
  83.     echo "Failed to read data from the pipe."
  84.  
  85. proc closePipe*() =
  86.   # Close the pipe (automatically disconnects client too)
  87.   discard closeHandle(pipe)
  88.  
  89. proc test() =
  90.  
  91.   var msgIn:Message
  92.  
  93.   connectPipe()
  94.  
  95.   while true:
  96.     if recvMessage(msgIn.addr): # does not block/wait
  97.         case msgIn.kind
  98.         of mkRotX: echo "received msg rotate x ", msgIn.value
  99.         of mkRotY: echo "received msg rotate y ", msgIn.value
  100.         of mkRotZ: echo "received msg rotate z ", msgIn.value
  101.         of mkQuit: echo "quit received"; break
  102.         else: discard
  103.  
  104.     sleep(500)
  105.  
  106.   closePipe()
  107.  
  108. when isMainModule:
  109.   test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement