-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpipe.cpp
More file actions
157 lines (141 loc) · 6.37 KB
/
pipe.cpp
File metadata and controls
157 lines (141 loc) · 6.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* File: NamedPipeServer.cpp
* Description: This file contains functions to create and manage a named pipe server in Windows.
* The server waits for a client to connect, handles incoming requests, and sends
* data segments or other responses based on the client's request.
*
* Functions:
* - createAndConnectPipe: Creates a named pipe and waits for a client to connect.
* - CheckForRequest: Checks if data is available from the client without blocking.
* - handleClientRequests: Handles requests from the client, including starting the experiment,
* sending data, and stopping the data acquisition.
*
* Usage:
* - Compile this file as part of your application that interacts with named pipes.
*
* Author: Frank Ran
* Created: 2024-11-13
* Notes:
* - Ensure the client application connects to the same named pipe for proper communication.
* - Customize the buffer size and request handling logic as needed.
*/
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
/*
* Function: createAndConnectPipe
* Description: Creates a named pipe with read/write access and waits for a client to connect.
* Parameters:
* - pipeName: The name of the pipe (const char*) used to identify the pipe.
* - bufferSize: The size of the pipe's buffer in bytes (DWORD).
* Returns:
* - HANDLE: A handle to the created pipe. Returns NULL if the pipe creation or connection fails.
* Notes:
* - The function blocks until a client connects to the pipe.
* - The created pipe has duplex (read/write) access with byte-based communication.
*/
extern "C" HANDLE createAndConnectPipe(const char* pipeName, DWORD bufferSize) {
HANDLE hPipe = CreateNamedPipe(
pipeName, // Pipe name passed as argument
PIPE_ACCESS_DUPLEX, // Read/Write access
PIPE_TYPE_BYTE | // Byte-type pipe
PIPE_READMODE_BYTE | // Byte-read mode
PIPE_WAIT, // Blocking mode
1, // Max number of instances
bufferSize, // Output buffer size
bufferSize, // Input buffer size
0, // Default timeout
NULL); // Default security attributes
if (hPipe == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to create named pipe.\n";
return NULL;
}
std::cout << "Waiting for client connection...\n";
BOOL connected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (!connected) {
std::cerr << "Failed to connect to the client.\n";
CloseHandle(hPipe);
return NULL;
}
return hPipe;
}
/*
* Function: CheckForRequest
* Description: Checks if the client has sent any data to the server without blocking.
* Parameters:
* - hPipe: A handle to the pipe (HANDLE) to check for available data.
* Returns:
* - bool: Returns true if data is available to read; false otherwise.
* Notes:
* - Uses PeekNamedPipe to check for data without removing it from the pipe.
*/
extern "C" bool CheckForRequest(HANDLE hPipe) {
DWORD bytesAvailable = 0;
if (PeekNamedPipe(hPipe, NULL, 0, NULL, &bytesAvailable, NULL) && bytesAvailable > 0) {
return true; // Data is available to read
}
return false; // No data available
}
/*
* Function: handleClientRequests
* Description: Handles requests from the client connected to the named pipe. Depending on the request,
* the function may start or stop the experiment, or send data back to the client.
* Parameters:
* - hPipe: A handle to the pipe (HANDLE) for communication.
* - data: Pointer to an array of short integers (short*) containing the raw signals data to send.
* - corrMatrix: Pointer to an array of doubles (double*) representing the correlation matrix to send.
* - segmentIndex: The index (int) of the data segment to send.
* - bytesToSend: The number of bytes to send (DWORD) from the `data` array, which means the number pf signal points sent.
* Returns:
* - int: Status code indicating the result:
* - 0: No data to process.
* - 1: Error occurred (e.g., reading or writing data).
* - 2: Experiment start requested.
* - 3: Data sent successfully.
* - 4: Experiment stop requested.
* Notes:
* - This function calls CheckForRequest to verify if the client has sent data.
* - The function uses `ReadFile` and `WriteFile` to read from and write to the pipe.
*/
extern "C" int handleClientRequests(HANDLE hPipe, short* data, double* corrMatrix, int segmentIndex, DWORD bytesToSend) {
if (!CheckForRequest(hPipe)) {
return 0; // No data to process
}
// Read the client's request
short request;
DWORD bytesRead;
BOOL success = ReadFile(hPipe, &request, sizeof(request), &bytesRead, NULL);
if (!success || bytesRead != sizeof(request)) {
std::cerr << "Failed to read request from client.\n";
return 1; // Error reading the request
}
if (request == 1) { // The client requested to start the experiment
return 2; // The client requested to start the experiment
}
else if (request == 2) { // The client requested to send data including raw signals and correlation matrix
DWORD bytesWritten1;
DWORD bytesWritten2;
// Calculate the starting position for the segment to send in the data array
short* segmentStart = data + (segmentIndex * (bytesToSend / sizeof(short))); // Calculate the starting point
// Send a segment of `data` to the client
success = WriteFile(hPipe, segmentStart, bytesToSend, &bytesWritten1, NULL);
if (!success || bytesWritten1 != bytesToSend) {
std::cerr << "Failed to send data segment to client.\n";
return 1; // Error sending the data segment
}
// Send the correlation matrix to the client
success = WriteFile(hPipe, corrMatrix, 512, &bytesWritten2, NULL);
if (!success || bytesWritten2 != 512) {
std::cerr << "Failed to send correlation matrix to client.\n";
return 1; // Error sending the correlation matrix
}
return 3;
}
else if (request == 3) { // The client requested to abort the experiment
return 4; // The client requested to stop experiement
}
else {
return 1; // Invalid request
}
}