Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #///////////////////////// client.nim /////////////////
- #
- #Client Program for Win32 Named Pipes Example.
- #Based on cpp example by Peter R. Bloomfield.
- #
- #For an explanation of the code, see the associated blog post:
- #http://avidinsight.uk/2012/03/introduction-to-win32-named-pipes-cpp/
- #https://github.com/avidinsight/win32-named-pipes-example/blob/master/src/client.cpp
- #
- #This code is made freely available under the MIT open source license
- #(see accompanying LICENSE file for details).
- #It is intended only for educational purposes. and is provide as-is with no
- #guarantee about its reliability, correctness, or suitability for any purpose.
- #
- #
- #TEST INSTRUCTIONS:
- #
- #Run the accompanying server program first.
- #Before closing it, run this client program.
- #
- import winlean, os
- import message
- const
- pipeHeaderName = r"\\.\pipe\mypipe" # must match name in server.nim
- const
- DEFAULT_PIPE_SIZE = 65536'i32
- FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000'i32
- PIPE_WAIT = 0x00000000'i32
- PIPE_TYPE_BYTE = 0x00000000'i32
- PIPE_READMODE_BYTE = 0x00000000'i32
- ERROR_PIPE_CONNECTED = 535
- ERROR_PIPE_BUSY = 231
- ERROR_BROKEN_PIPE = 109
- ERROR_PIPE_NOT_CONNECTED = 233
- var pipe:Handle
- proc connectPipe*() =
- echo "Connecting to pipe..."
- # Open the named pipe
- var pipeName = newWideCString(pipeHeaderName)
- var sa = SECURITY_ATTRIBUTES(nLength: sizeof(SECURITY_ATTRIBUTES).cint,
- lpSecurityDescriptor: nil, bInheritHandle: 1)
- pipe = createFileW(pipeName, GENERIC_READ, # only need read access
- 0, sa.addr, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, 0)
- if pipe == INVALID_HANDLE_VALUE:
- echo "Failed to connect to pipe."
- let err = osLastError()
- if err.int32 != ERROR_PIPE_BUSY:
- raiseOsError(err)
- proc recvMessage*(buffer: ptr Message ):bool =
- #echo "Reading data from pipe..."
- result = false
- var
- msglen = 0.int32
- res = 0.int32
- try:
- discard pipe.peekNamedPipe(cast[pointer](buffer),sizeof(Message).int32, msglen.addr) # not blocked
- except:
- return false
- if msglen == 0:
- return false
- var numBytesRead:int32 = 0
- try:
- res = readFile(pipe, cast[pointer](buffer), # the data from the pipe will be put here
- sizeof(Message).int32,
- numBytesRead.addr, # this will store number of bytes actually read
- nil)
- except:
- return false
- if res > 0:
- # echo "Number of bytes read: ", numBytesRead
- # echo "Message: ", buffer[]
- return true
- else:
- echo "Failed to read data from the pipe."
- proc closePipe*() =
- # Close the pipe (automatically disconnects client too)
- discard closeHandle(pipe)
- proc test() =
- var msgIn:Message
- connectPipe()
- while true:
- if recvMessage(msgIn.addr): # does not block/wait
- case msgIn.kind
- of mkRotX: echo "received msg rotate x ", msgIn.value
- of mkRotY: echo "received msg rotate y ", msgIn.value
- of mkRotZ: echo "received msg rotate z ", msgIn.value
- of mkQuit: echo "quit received"; break
- else: discard
- sleep(500)
- closePipe()
- when isMainModule:
- test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement