-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.cpp
More file actions
146 lines (120 loc) · 4.41 KB
/
server.cpp
File metadata and controls
146 lines (120 loc) · 4.41 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
#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#define BUFSIZE 1024
#define PIPE_TIMEOUT 5000
using namespace std;
// Функция для чтения слов из файла
vector<string> readF(const string& filename) {
vector<string> words;
ifstream file(filename);
if (!file.is_open()) {
cerr << "Error opening file: " << filename << endl;
return words;
}
string word;
while (file >> word) {
words.push_back(word);
}
file.close();
return words;
}
int main(int argc, char* argv[]) {
// Проверка аргументов командной строки
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <number of clients>" << endl;
return 1;
}
int numClients = atoi(argv[1]);
if (numClients < 3) {
cerr << "Number of clients must be at least 3" << endl;
return 1;
}
// Запрос имени файла у пользователя
cout << "Enter filename: ";
string filename;
getline(cin, filename);
// Чтение слов из файла
vector<string> words = readF(filename);
if (words.empty()) {
cout << "File is empty or cannot be read." << endl;
return 1;
}
cout << "Found " << words.size() << " words in the file." << endl;
cout << "Waiting for " << numClients << " clients to connect..." << endl;
// Создание именованных каналов для каждого клиента
vector<HANDLE> hPipes(numClients);
for (int i = 0; i < numClients; i++) {
string pipeName = "\\\\.\\pipe\\worddist_pipe_" + to_string(i);
hPipes[i] = CreateNamedPipeA(
pipeName.c_str(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
numClients,
BUFSIZE * 4,
BUFSIZE * 4,
PIPE_TIMEOUT,
NULL);
if (hPipes[i] == INVALID_HANDLE_VALUE) {
cerr << "Error creating pipe for client " << i << ". GLE=" << GetLastError() << endl;
return -1;
}
}
// Ожидание подключения всех клиентов
for (int i = 0; i < numClients; i++) {
cout << "Waiting for client " << i << " to connect..." << endl;
BOOL connected = ConnectNamedPipe(hPipes[i], NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (!connected) {
cerr << "Error connecting client " << i << ". GLE=" << GetLastError() << endl;
CloseHandle(hPipes[i]);
return -1;
}
cout << "Client " << i << " connected successfully" << endl;
}
// Распределение слов между клиентами
int currentClient = 0;
for (size_t i = 0; i < words.size(); i++) {
DWORD dwWritten;
string word = words[i];
BOOL fSuccess = WriteFile(
hPipes[currentClient],
word.c_str(),
word.size(),
&dwWritten,
NULL);
if (!fSuccess) {
cerr << "Error writing to client " << currentClient << ". GLE=" << GetLastError() << endl;
break;
}
cout << "Sent to client " << currentClient << ": " << word << endl;
// Получение подтверждения от клиента
char buffer[BUFSIZE];
DWORD dwRead;
fSuccess = ReadFile(
hPipes[currentClient],
buffer,
BUFSIZE,
&dwRead,
NULL);
if (!fSuccess || dwRead == 0) {
cerr << "Error reading from client " << currentClient << ". GLE=" << GetLastError() << endl;
break;
}
buffer[dwRead] = '\0';
cout << "Client " << currentClient << " acknowledgment: " << buffer << endl;
// Переход к следующему клиенту
currentClient = (currentClient + 1) % numClients;
}
// Завершение работы - отправка сообщения о завершении всем клиентам
for (int i = 0; i < numClients; i++) {
DWORD dwWritten;
string endMsg = "END";
WriteFile(hPipes[i], endMsg.c_str(), endMsg.size(), &dwWritten, NULL);
CloseHandle(hPipes[i]);
}
cout << "Word distribution completed successfully." << endl;
}