Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811

Winsock2 в классе

12.01.2016, 08:32. Показов 2333. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решил сделать класс для дальнейшего применения в разных программах вот что получилось:
Файл Konnekt.срр
C++
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
#include "stdafx.h"
 
 
Konnekt::Konnekt(PCSTR a)
{   
    DEFAULT_PORT = a;
    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
    aa = 0;
    
    recvbuflen = DEFAULT_BUFLEN;
}
 
LPVOID Konnekt::otkr_soketa()
{
    setlocale(LC_ALL, "Russian");
nahalo:
 
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if ( iResult != 0 )
    {
        std::cout <<"WSAStartup произошла ошибка инициализации при запуске блок "<< '\n';
        goto nahalo;
    }   
 
    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 )
    {
        std::cout << "getaddrinfo произошла ошибка инициализации при запуске (void блок) " << '\n';
        WSACleanup();
        goto nahalo;
    }
 
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if ( ListenSocket == INVALID_SOCKET )
    {
        std::cout << "WSAStartup socket произошла ошибка инициализации при запуске (void блок) " << '\n';
        freeaddrinfo(result);
        WSACleanup();
        goto nahalo;
    }
 
    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if ( iResult == SOCKET_ERROR )
    {
        std::cout << "bind произошла ошибка инициализации при запуске (void блок) " << '\n';
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        goto nahalo;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, 0x100);//размер очереди  0x100
    if ( iResult == SOCKET_ERROR )
    {
        std::cout << "WSAStartup listen произошла ошибка инициализации при запуске (void блок) " << '\n';
        closesocket(ListenSocket);
        WSACleanup();
        goto nahalo;
    }//установление соединения с сокетом
    do//цикл подключение очередного сокета
    {
        std::cout << "Ожидаем подключение клиента" << '\n';
        ClientSocket = accept(ListenSocket, NULL, NULL); //ожидание подключения нового клиента
        
        std::thread новый_поток(&potok_новый);
        новый_поток.detach();//Отсоединение потока
        
    }
    while ( ClientSocket != INVALID_SOCKET );//закрытие цикла при ошибке инициализации сокета
    std::cout << "при ожидании нового клиента произошла ошибка " << '\n';
    closesocket(ClientSocket);
    WSACleanup();
    goto nahalo;
    return 0;
}
int Konnekt::priem_paketa()
{
    //проверка разрыва соединения
    struct tcp_keepalive alive;
    DWORD dwRet, dwSize;
    alive.onoff = 1;
    alive.keepalivetime = 1000;
    alive.keepaliveinterval = 100;
    dwRet = WSAIoctl(ClientSocket, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
                     NULL, 0, reinterpret_cast<DWORD*>(&dwSize), NULL, NULL);
    if ( dwRet == SOCKET_ERROR )
    {
        closesocket(ClientSocket);
        WSACleanup();
        std::cout << "Соединение закрыто  в структуре tcp_keepalive" << '\n';
        return 0;
    }
    int iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);//чтение сообщение
    std::cout << "iResult = " << iResult << '\n';
    for ( int a = 0; a <= iResult; a++ )
    {
        std::cout << recvbuf[a] << " ";
    }
    std::cout << '\n';
    if ( iResult == INVALID_SOCKET )
    {
        closesocket(ClientSocket);//закрываем сокет из за ошибки 
        std::cout << "сокет закрыт " << '\n';
    }
    return 0;
}
 
void Konnekt::potok_новый()
{
    priem_paketa();
    //return 0;
}
Konnekt::~Konnekt()
{
    closesocket(ClientSocket);//закрываем сокет из за ошибки 
    closesocket(ListenSocket);
}
Файл Konnekt.h
C++
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
#pragma once
#define DEFAULT_BUFLEN 1024//размер буфера приема
class Konnekt
{
public:
    PCSTR DEFAULT_PORT;
    WSADATA wsaData;
    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL;
    struct addrinfo hints;
    int iResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen;
    int aa;
 
    
    Konnekt(PCSTR);
    LPVOID otkr_soketa();
    int priem_paketa();
    void potok_новый();
 
 
    ~Konnekt();
};
ну и майн:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
 
 
int main()
{
 
    Konnekt kon1("11000");//создаем объект и иницилизируем адресом порта
    kon1.otkr_soketa();//устанавливаем соединение
    
    system("pause");
    return 0;
}
Загвоздка получилась в создании потока в файле Konnekt.срр строка 75 std::thread новый_поток(&potok_новый);

Ошибка C2276 &: недопустимая операция с выражением привязанной функции-члена Consoleserver_1.0 C:\Users\Administrator\Desktop\Проекты\C onsoleserver_1.0\Consoleserver_1.0\Konne kt.cpp 76

Вроде поток оргонизовываю правельно... в чем проблема?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.01.2016, 08:32
Ответы с готовыми решениями:

winsock2.h
Компилирую обычный код: #pragma comment(lib, &quot;ws2_32&quot;) #include &lt;winsock2.h&gt; int main() { } Ошибки: 1&gt;------...

winsock2
Помогите, вот код: if(WSAConnect(sock, (SOCKADDR*)&amp;addr, sizeof(addr))) { cout &lt;&lt; &quot;Connected!&quot;; ...

Уроки по WinSock2 C++
Всем привет, решил записать небольшую серию уроков по сокетам в C++. Кому интересно вот видео: https://youtu.be/CRFNbq2pBxM Вот...

26
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
12.01.2016, 11:26
Цитата Сообщение от eagl69 Посмотреть сообщение
C++
1
std::thread новый_поток(&potok_новый);
C++
1
std::thread новый_поток(&Konnekt::potok_новый,this);
1
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
12.01.2016, 13:16  [ТС]
Спасибо! а то я голову чуть не сломал....

Добавлено через 1 час 14 минут
Ну а как в общем я в правильном направлении иду? или намудрил лишнего. Хочу такой класс который можно будет легко подключать к проектам и который будет осуществлять многомопочный коннект, принимать и предоставленные ему данные.
0
 Аватар для uhx
60 / 60 / 19
Регистрация: 11.07.2013
Сообщений: 305
12.01.2016, 14:40
Все данные в классе лучше всего закрыть в private. Тем более, когда приложение многопоточно.
Нужно обеспечить асинхронный доступ к данным, почитай про mutex
Крайне не рекомендуется использовать goto
У тебя работа идет лишь с последним сокетом. За время создания потока может появиться еще одно подключение, и тогда два потока будут работать с одним сокетом, а при синхронной работе это вообще не хорошо.
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
12.01.2016, 15:01  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
do//цикл подключение очередного сокета
    {
        std::cout << "Ожидаем подключение клиента" << '\n';
        ClientSocket = accept(ListenSocket, NULL, NULL); //ожидание подключения нового клиента
        
        std::thread новый_поток(&potok_новый);
        новый_поток.detach();//Отсоединение потока
        
    }
    while ( ClientSocket != INVALID_SOCKET );//закрытие цикла при ошибке инициализации сокета
В этом цикле хотел добиться что при новом подключении запускается поток, отсоединяется и ждется второе подключение.... разве не будет так работать?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.01.2016, 11:25
Цитата Сообщение от eagl69 Посмотреть сообщение
В этом цикле хотел добиться что при новом подключении запускается поток, отсоединяется и ждется второе подключение.... разве не будет так работать?
отсоединять не надо, текущий поток продолжит выполнения и без отсоебинений побочного, только побочный потом надо заджойнить std::thread::join()

Добавлено через 1 минуту
Цитата Сообщение от eagl69 Посмотреть сообщение
разве не будет так работать?
uhx, гововрит о том что ClientSocket измениться когда подключится новый клиент и оба потока будут обрабатывать один сокет, а предыдущий посто потеряется
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 12:00  [ТС]
Если сделаем std::thread::join() то вроде тогда будем ждать завершение потока в этом случае многопоточность не получится. а отсоединяю как раз для того чтобы этот поток продолжил работу и перешел к ожиданию подключения второго клиента....
Цитата Сообщение от aLarman Посмотреть сообщение
uhx, гововрит о том что ClientSocket измениться
это Вы про что?

C++
1
2
3
4
5
6
7
8
9
do//цикл подключение очередного сокета
    {
        std::cout << "Ожидаем подключение клиента" << '\n';
        ClientSocket = accept(ListenSocket, NULL, NULL); //ожидание подключения нового клиента
        
        std::thread новый_поток(&potok_новый);
        новый_поток.detach();//Отсоединение потока если пишем std::thread::join() то тогда ждем завершения потока?
        
    }
0
 Аватар для uhx
60 / 60 / 19
Регистрация: 11.07.2013
Сообщений: 305
13.01.2016, 12:30
Во время создания потока ClientSocket в классе может изменится (новое подкл.), тогда два потока будут обрабатывать один сокет. Такого допускать нельзя, потокам нужно обеспечить асинхронный доступ к необходимому блоку памяти, в этом вам поможет mutex. Вообще почитайте про многопоточность. Я конечно далеко не спец, но мне кажется потоки в одном классе лучше не использовать... А если и использовать, то сделать их независимыми от переменных внутри класса (напр. ClientSocket)
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 12:35  [ТС]
Да я тоже уже подумал, что если создается 2 потока то прием ведется в одну переменную а это не правильно... нужно объявлять буфер приема отправки уже в потоке...

Добавлено через 1 минуту
Цитата Сообщение от uhx Посмотреть сообщение
У тебя работа идет лишь с последним сокетом. За время создания потока может появиться еще одно подключение, и тогда два потока будут работать с одним сокетом, а при синхронной работе это вообще не хорошо.
А как тогда выходить из этой ситуации? в гугле искал примеры, там как раз они основаны на создании отдельных потоков по обработке сокетов...
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.01.2016, 12:42
Цитата Сообщение от eagl69 Посмотреть сообщение
А как тогда выходить из этой ситуации? в гугле искал примеры, там как раз они основаны на создании отдельных потоков по обработке сокетов...
завести массив сокетов подключенных клиентов, ну или список по идее это не суть, а при приеме данных каждый раз выделять буфер - чтобы он был индивидуальный например

Добавлено через 1 минуту
Цитата Сообщение от eagl69 Посмотреть сообщение
Если сделаем std::thread::join() то вроде тогда будем ждать завершение потока в этом случае многопоточность не получится. а отсоединяю как раз для того чтобы этот поток продолжил работу и перешел к ожиданию подключения второго клиента....
так join то надо делать в деструкторе класса, а не после создания потока(типо вместо detach)
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 12:42  [ТС]
Цитата Сообщение от aLarman Посмотреть сообщение
завести массив сокетов подключенных клиентов, ну или список по идее это не суть,
Не подскажите как это сделать? про отдельный буфер я уже понял
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.01.2016, 12:46
вообще варинтов много
1) пул потоков(читать на просторах интернета, объяснять долго но в 2х словах: есть фиксированное кол-во потоков по кол-ву ядер например и им раздаются задания)
2) каждое подключение - новый поток(тут проблема много подключившихся, много потоков а это ограниченный ресурс)
3) асинхронный ввод\вывод и все делать в 1ом потоке(порядка 100 клиентов без проблем отработают)

Добавлено через 2 минуты
Цитата Сообщение от eagl69 Посмотреть сообщение
Не подскажите как это сделать?
ну....кстати еще проще можно, можно в метода передать сокет просто и все, и каждый поток будет со своим работать)
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 13:04  [ТС]
А еще сделать новый класс где будет описан этот поток? и в новый поток отдавать уже этот класс? или это уже слишком ?
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.01.2016, 13:32
Цитата Сообщение от eagl69 Посмотреть сообщение
А еще сделать новый класс где будет описан этот поток? и в новый поток отдавать уже этот класс? или это уже слишком ?
да можно в конструкторе этого создавать, feel free

Добавлено через 2 минуты
Вы бы все же сказали поконкретнее какие функциональные требования, а то все "вилами на воде"
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 14:02  [ТС]
Требования, класс который можно будет подключать к проектам и который будет осуществлять многопоточный прием и отправку сообщений клиентам. Для создания многопоточного сервера например...
0
654 / 575 / 164
Регистрация: 13.12.2012
Сообщений: 2,124
13.01.2016, 14:58
но существуют же готовые решения, например PoCo или Вы желаете сами написать
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
13.01.2016, 17:26  [ТС]
Интересно самому.. тренировка опять же и появляется понимание
0
50 / 49 / 10
Регистрация: 24.01.2010
Сообщений: 225
14.01.2016, 00:41
про код промолчу. резко отрицательно. лучше начните с коцепции. вот это

C++
1
int Konnekt::priem_paketa()
в корне не верно
в TCP НЕТ ПАКЕТОВ на пользовательском уровне

(круглый)
ЗЫ
Типичная ошибка большинства...
0
11 / 15 / 8
Регистрация: 12.10.2011
Сообщений: 811
14.01.2016, 06:31  [ТС]
Вы обратили только на название? это я образно назвал только потому, что клиент (блок телематики) шлет как бы пакеты информации это только для себя...
Ну а что на счет самого кода всегда рад выслушать замечания... на счет goto я тоже в курсях это сделал на время только для проб и отладки... хотя а почему бы и нет именно здесь? и оно ни разу не срабатывало

Ну вот в принципе я добился чего хотел, может подключится одновременно несколько клиентов и сервер пока отправляет в ответ то что пришло от клиента... Вопрос вот в чем: например у нас подключилось 5 клиентов, открылось 5 потоков а как мне выбрать именно тот поток для отправки данных например 3 клиенту? т.е. задача отправлять данные в любое время необходимому мне клиенту....
0
50 / 49 / 10
Регистрация: 24.01.2010
Сообщений: 225
14.01.2016, 08:33
"в корне не верно" это от слова совсем.

это как если-бы вам говорили, что машина хэчтбак, а Вы бы угаваривали поднять маленькую плиту весом не 2 тонны а всего 1,5 тонны

протокол TCP потоковый. нет там в природа пакетов. посылайте хоть по 10, 20 или по 1500 - ну нет там пакетов физически...Пример:

вам пошлют
50+50+50+50+50
Вы можете принять
50+10+30+150+10

т.е. квантованости НИКТО не обещал!

(круглый)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.01.2016, 08:33
Помогаю со студенческими работами здесь

winsock2 и dns
Подскажите как при использовании winsock2 можно узнать ip по dns-имени сайта? Язык c++.

Книги по winsock2
Здравствуйте! Посоветуйте книги для изучения сетевого программирования (winsock2) на C/C++. А так же интересует вопрос, можно ли будет...

WinSock и WinSock2
Подскажите книги,литературу по winsock и winsock2.Я не совсем новичек но въехать в сокеты немогу

Не работает WinSock2.h
Привет, у меня серьезная проблема: программа ругается на веб-программу. То есть я создаю простейший сервер на сокетах, но при компиляции...

Скачать изображение winsock2
Делаю запрос на сервер для скачивания изображения (сохранять его на комп не надо, нужно работать с ним в памяти). Сам запрос формируется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru