Re: Потоки
https://uk.wikipedia.org/wiki/Багатониткова_безпека
В англійській версії є деталі, як її досягати.
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Потоки
Для відправлення відповіді ви повинні увійти або зареєструватися
https://uk.wikipedia.org/wiki/Багатониткова_безпека
В англійській версії є деталі, як її досягати.
const boost::system::error_code& що означає ось цей рядок? Бо на сайті він написаний в функції, але не використовується, мабудь.
Чекайте, може, колись на форумі зареєструється телепат і зможе вам відповісти.
#include <iostream>
#include <boost/asio.hpp>
#include <chrono>
#include <thread>
void printline(const boost::system::error_code&ercd)
{
std::cout << "printline" << std::endl;
}
int main(void)
{
/*boost::asio::io_context ioct;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2000));
std::cout << "ioct" << std::endl;
sytr.wait();
std::cout << "ioct" << std::endl;*/
/*boost::asio::io_context ioct;
std::cout << "ptl0" << std::endl;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2500));
sytr.wait();
std::cout << "ptl1" << std::endl;
sytr.async_wait(&printline);
std::cout << "ptl2" << std::endl;
ioct.run();*/
/*boost::asio::io_context ioct;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2500));
std::cout << "ptl0" << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(3000));
std::cout << "ptl1" << std::endl;
sytr.wait();
std::cout << "ptl2" << std::endl;
*/
boost::asio::io_context ioct;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(10000));
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "mainline" << std::endl;
sytr.async_wait(&printline);
std::cout << "mainline" << std::endl;
ioct.run();
std::cout << "кінець" << std::endl;
return 0;
}
І що ж саме у виразі
/*boost::asio::io_context ioct;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2000));
std::cout << "ioct" << std::endl;
sytr.wait();
std::cout << "ioct" << std::endl;*/
/*boost::asio::io_context ioct;
std::cout << "ptl0" << std::endl;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2500));
sytr.wait();
std::cout << "ptl1" << std::endl;
sytr.async_wait(&printline);
std::cout << "ptl2" << std::endl;
ioct.run();*/
void printline(const boost::system::error_code&ercd)
/*boost::asio::io_context ioct;
boost::asio::steady_timer sytr(ioct, boost::asio::chrono::milliseconds(2500));
std::cout << "ptl0" << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(3000));
std::cout << "ptl1" << std::endl;
sytr.wait();
std::cout << "ptl2" << std::endl;
*/
вам незрозуміло? (трохи підредагував, викинув деякі зайві рядки)
Погортайте вище. Я питався про "const boost::system::error_code&". Без цього рядку не працює метод async_wait. На сайті він прописаний, але пояснення не надані. Тому й питаю нащо...
Ось https://www.boost.org/doc/libs/1_75_0/d … imer2.html
Якщо ви за вашим посиланням перейдете за steady_timer::async_wait(), то прочитаєте те, що вам треба.
П.С. Відповідь на ваше перше питання - проголошення змінної (або параметра функції) типу "посилання на константний boost::system::error_code".
Підкажіть хтось, будь ласка , як краще реалізувати функцію sendoneposmess, бо пів дня сиджу... Можливо можна якось мудріше реалізувати не можу знайти ынфлрмацыъ в інтернеті.
ось код сервера
#include <iostream>
#include <thread>
#include <WinSock2.h>
#include <string>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)
struct person
{
std::string name;
int pass;
person* next;
};
const int size = 10;
SOCKET massaccept[size];
std::thread massth[size];
person *massper;
void line(person** per, std::string nm, int passione)
{
if ((*per) == nullptr)
{
(*per) = new person;
(*per)->name = nm;
(*per)->pass = passione;
(*per)->next = nullptr;
}
else
{
if ((*per) != nullptr)
{
person* last = (*per);
while (last->next != nullptr)
{
last = last->next;
}
last->next = new person;
last = last->next;
last->name = nm;
last->pass = passione;
last->next = nullptr;
}
}
return;
}
bool findpass(person* fd)
{
person* find = massper;
while (find != nullptr)
{
if (find->name == fd->name && find->pass == fd->pass)
{
return true;
}
find = find->next;
}
return false;
}
int findname(std::string name)
{
person* find = massper;
int i = 0;
while (find != nullptr)
{
if (find->name == name)
{
return i;
}
i = i + 1;
find = find->next;
}
return -1;
}
enum option
{
sendallmess,
sendoneposmess,
sendservermes,
takemes,
closesock,
takeprivate
};
bool funcop(option op, int sock)
{
switch (op)
{
case sendallmess:
{
char* mes = nullptr;
int sizemess = 0;
recv(massaccept[sock], (char*)&sizemess, sizeof(int), NULL);
mes = new char[sizemess];
recv(massaccept[sock], mes, sizemess, NULL);
for (int i = 0; i < size; i++)
{
if (i == sock)
{
i = i;
}
else
{
option a = option::takemes;
send(massaccept[i], (char*)&a, sizeof(option), NULL);
send(massaccept[i], (char*)&sizemess, sizeof(int), NULL);
send(massaccept[i], mes, sizemess, NULL);
}
}
delete[]mes;
return true;
}
case sendservermes:
{
char* mes = nullptr;
int sizemess = 0;
recv(massaccept[sock], (char*)&sizemess, sizeof(int), NULL);
mes = new char[sizemess];
recv(massaccept[sock], mes, sizemess, NULL);
std::cout << mes;
return true;
}
case closesock:
{
std::cout << "Зв'язок розірвано." << std::endl;
int pos = 0;
option a = option::takemes;
send(massaccept[sock],(char*)&a, sizeof(option), NULL);
send(massaccept[sock], (char*)&pos, sizeof(int), NULL);
closesocket(massaccept[sock]);
return false;
}
case sendoneposmess:
{
char* nm = nullptr;
int sz = 0;
recv(massaccept[sock], (char*)&sz, sizeof(int), NULL);
nm = new char[sz];
recv(massaccept[sock], nm, sz, NULL);
int sen = findname(std::string(nm));
std::cout << sen;
send(massaccept[sock], (char*)&sen, sizeof(int), NULL);
if (sen != -1)
{
char* mes = nullptr;
int sizemess = 0;
recv(massaccept[sock], (char*)&sizemess, sizeof(int), NULL);
mes = new char[sizemess];
recv(massaccept[sock], mes, sizemess, NULL);
option a = takeprivate;
send(massaccept[sen], (char*)&a, sizeof(option), NULL);
send(massaccept[sen], (char*)&sizemess, sizeof(int), NULL);
send(massaccept[sen], (char*)&mes, sizemess, NULL);
}
return true;
}
default:
{
std::cout << "Пакет недоступний." << std::endl;
return false;
}
}
}
void work(int pos)
{
bool wo = true;
while (wo == true)
{
option op = sendallmess ;
recv(massaccept[pos], (char*)&op, sizeof(option), NULL);
wo = funcop(op, pos);
}
}
int main(void)
{
setlocale(LC_ALL, "");
WSAData data;
WORD word = MAKEWORD(2, 2);
person* serv = nullptr;
if (WSAStartup(word, &data) != 0)
{
std::cout << "Не вдалося завантажити бібліотеку." << std::endl;
return 1;
}else
{
sockaddr_in soin;
soin.sin_addr.s_addr = inet_addr("127.0.0.1");
soin.sin_port = htons(666);
soin.sin_family = AF_INET;
int size = sizeof(soin);
SOCKET mainsock = socket(AF_INET, SOCK_STREAM, NULL);
bind(mainsock, (sockaddr*)&soin, size);
listen(mainsock, SOMAXCONN);
for (int i = 0; i < size; i++)
{
SOCKET newaccept = accept(mainsock, (sockaddr*)&soin, &size);
if (newaccept == 0)
{
std::cout << "Клієнт не підключений." << std::endl;
closesocket(newaccept);
}
else
{
person* find = new person;
recv(newaccept, (char*)find, sizeof(person), NULL);
line(&massper, "135", 53113316);
line(&massper, "1ggeq", 533111316);
line(&massper, find->name,find->pass);
bool close = findpass(find);
if (close == false)
{
std::cout << "Невдала спроба входу." << std::endl;
send(newaccept, (char*)&close, sizeof(bool), NULL);
closesocket(newaccept);
}
else
{
send(newaccept, (char*)&close, sizeof(bool), NULL);
std::cout << "Клієнт " << find->name << " підключений." << std::endl;
std::string mess = "Вітаємо на сервері ";
std::string nim = find->name;
std::string en = ".";
std::string line = mess + nim + en;
line.push_back('\n');
line.push_back('\0');
int sizemess = line.size();
send(newaccept, (char*)&sizemess, sizeof(int), NULL);
send(newaccept, line.c_str(), sizemess, NULL);
/*char* mes = nullptr;
int pos = NULL;
recv(newaccept, (char*)&pos, sizeof(int), NULL);
mes = new char[pos];
recv(newaccept, mes, pos, NULL);
std::cout << mes;
delete[] mes;*/
massaccept[i] = newaccept;
massth[i] = std::thread(work, i);
}
}
}
}
for (int i = 0; i < size; i++)
{
massth[i].join();
}
WSACleanup();
return 0;
}
ось код клієнта
#include <iostream>
#include <string>
#include <WinSock2.h>
#include <thread>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)
SOCKET mainsock;
struct person
{
std::string name;
int pass;
person* next;
};
person* newper = new person;
enum option
{
sendallmess,
sendoneposmess,
sendservermes,
takemes,
closesock,
takeprivate
};
bool funcop(option op)
{
switch (op)
{
case sendallmess:
{
std::string premes = "Вам надійшло повідомлення: ";
std::string mes;
std::cin >> mes;
std::string line = premes + mes;
line.push_back('\n');
line.push_back('\0');
int size = line.size();
option sendall = sendallmess;
send(mainsock, (char*)&sendall, sizeof(option), NULL);
send(mainsock, (char*)&size, sizeof(int), NULL);
send(mainsock, line.c_str(), size, NULL);
return true;
}
case takemes:
{
char* mes = nullptr;
int sizemess = NULL;
recv(mainsock, (char*)&sizemess, sizeof(int), NULL);
if (sizemess == 0)
{
return false;
}
else
{
mes = new char[sizemess];
recv(mainsock, mes, sizemess, NULL);
std::cout << mes;
delete[] mes;
return true;
}
}
case sendservermes:
{
std::string premes = "Вам надійшло повідомлення від ";
std::string mes;
std::string nm = newper->name;
std::string last = ": ";
std::cin >> mes;
std::string line = premes + nm + last + mes;
line.push_back('\n');
line.push_back('\0');
int size = line.size();
option sendall = sendservermes;
send(mainsock, (char*)&sendall, sizeof(option), NULL);
send(mainsock, (char*)&size, sizeof(int), NULL);
send(mainsock, line.c_str(), size, NULL);
return true;
}
case closesock:
{
option op = option::closesock;
send(mainsock, (char*)&op, sizeof(option), NULL);
std::cout << "Зв'язок розірвано." << std::endl;
return false;
}
case sendoneposmess:
{
std::cout << "Введіть ім'я користувача: ";
std::string nam;
std::cin >> nam;
int ln = 0;
option c = sendoneposmess;
nam.push_back('\0');
ln = nam.size();
send(mainsock, (char*)&c, sizeof(option), NULL);
send(mainsock, (char*)&ln, sizeof(int), NULL);
send(mainsock, nam.c_str(), ln, NULL);
int sen = -1;
recv(mainsock, (char*)&sen, sizeof(int), NULL);
if (sen != -1)
{
std::cout << "Введіть повідомлення користувачу " << nam << ": ";
std::string premes = "Вам надійшло повідомлення від ";
std::string pi = newper->name;
std::string last = ": ";
std::string mes;
std::cin >> mes;
std::string line = premes + pi + last + mes;
line.push_back('\n');
line.push_back('\0');
int size = line.size();
send(mainsock, (char*)&size, sizeof(int), NULL);
send(mainsock, line.c_str(), size, NULL);
}
return true;
}
case takeprivate:
{
char* mes = nullptr;
int sizemess = 0;
recv(mainsock, (char*)&sizemess, sizeof(int), NULL);
mes = new char[sizemess];
recv(mainsock, mes, sizemess, NULL);
std::cout << mes;
return true;
}
default:
std::cout << "Пакет недоступний." << std::endl;
return false;
}
return true;
}
void take()
{
bool po = true;
while (po == true)
{
option a = takemes;
recv(mainsock, (char*)&a, sizeof(option), NULL);
po = funcop(a);
}
return;
}
void work()
{
bool bo = true;
while (bo == true)
{
std::cout << "Введіть операцію (0 - sendallmess, 1 - sendoneposmess, 2 - sendservermes, 3 - closesock): " << std::endl;
int pos = 0;
std::cin >> pos;
switch (pos)
{
case 0:
{
option op = option::sendallmess;
bo = funcop(op);
break;
}
case 1:
{
option op = option::sendoneposmess;
bo = funcop(op);
break;
}
case 2:
{
option op = option::sendservermes;
funcop(op);
break;
}
case 3:
{
option op = option::closesock;
bo = funcop(op);
break;
}
default:
std::cout << "Помилка." << std::endl;
break;
}
}
}
int main(void)
{
setlocale(LC_ALL, "");
WSAData data;
WORD word = MAKEWORD(2, 2);
std::thread mas[2];
newper->name = "Qlo";
newper->pass = 123;
if (WSAStartup(word, &data) != 0)
{
std::cout << "Не вдалось завантажити бібліотеку." << std::endl;
return 1;
}
else
{
sockaddr_in soin;
soin.sin_addr.s_addr = inet_addr("127.0.0.1");
soin.sin_port = htons(666);
soin.sin_family = AF_INET;
int size = sizeof(soin);
mainsock = socket(AF_INET, SOCK_STREAM, NULL);
SOCKET connserv = connect(mainsock, (sockaddr*)&soin, size);
if (connserv != 0)
{
std::cout << "Не вдалося підключитись до серверу." << std::endl;
return 2;
}
else
{
std::cout << "Підключено до серверу." << std::endl;
bool lock = false;
send(mainsock, (char*)newper, sizeof(person), NULL);
recv(mainsock, (char*)&lock, sizeof(bool), NULL);
if (lock == false)
{
std::cout << "Помилка входу." << std::endl;
return 10;
}
else
{
int sizemes = NULL;
char* mes = nullptr;
recv(mainsock, (char*)&sizemes, sizeof(int), NULL);
mes = new char[sizemes];
recv(mainsock, mes, sizemes, NULL);
std::cout << mes;
mas[0] = std::thread(work);
mas[1] = std::thread(take);
}
}
}
for (int i = 0; i < 2; i++)
{
mas[i].join();
}
WSACleanup();
return 0;
}
Хочу щоб повідомлення відправлялось конкретному користувачеві, а не всім разом, як реалізовано у першій функ
Я, мабуть , зрозумів проблему. Там функція, яка отримує повідомлення краде дані постійно, і вони не оброблюються в основній функції (для віфдправки певній особі) . Але без поняття як це виправити
В мене походу шиза, сам з собою спілкуюсь. Видальте останні декілька моїх повідомлень, будь ласка)
В мене походу шиза, сам з собою спілкуюсь. Видальте останні декілька моїх повідомлень, будь ласка)
Для відправлення відповіді ви повинні увійти або зареєструватися