Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
0 / 0 / 0
Регистрация: 19.04.2018
Сообщений: 17

Добавление нескольких клиентов в TCP сервере winsock

25.04.2020, 14:43. Показов 5197. Ответов 4

Студворк — интернет-сервис помощи студентам
Прилично плаваю в c++ и программировании в целом, но есть задание написать сервер под трех клиентов, которые будут отправлять файлы. Сколько ни пытался и не смотрел разные гайды и сайты, так и не понял как привести свой эхо сервер под несколько клиентов. Помогите, что и где нужно добавить.
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
#include "stdafx.h"
#include <iostream>
#include <string>
#include "WS2tcpip.h"
#include <stdio.h>
#include <time.h>
#include <fstream>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)
using namespace std;
 
void main(){
    
 
    WSADATA wsData;
    WORD ver = MAKEWORD(2, 2);
    int wsOk = WSAStartup(ver, &wsData);
    if (wsOk != 0)
    {
        cerr << "Cant initialize winsock! Bye Bye" << endl;
        return;
    }
 
    SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
    if (listening == INVALID_SOCKET)
    {
        cerr << "Cant create a socket! Bye bye" << endl;
        return;
    }
 
    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(54000);
    hint.sin_addr.S_un.S_addr = INADDR_ANY;
 
    bind(listening, (sockaddr*)&hint, sizeof(hint));
 
    listen(listening, SOMAXCONN);
 
    sockaddr_in client;
    int clientSize = sizeof(client);
 
    SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
    
        char host[NI_MAXHOST];
        char service[NI_MAXSERV];
 
 
        ZeroMemory(host, NI_MAXHOST);
        ZeroMemory(service, NI_MAXSERV);
 
        if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
        {
            time_t tm = time(NULL);
            cout << host << " Connected on port " << service << " at " << ctime(&tm) << endl;
 
        }
        else
        {
            time_t tm = time(NULL);
            inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
            cout << host << "connected on port " << ntohs(client.sin_port) << " at " << ctime(&tm) << endl;
        }
    
        closesocket(listening);
 
        char buf[4096];
 
        while (true)
        {
            ZeroMemory(buf, 4096);
            int byteReceived = recv(clientSocket, buf, 4096, 0);
            if (byteReceived == SOCKET_ERROR)
            {
                cerr << "Error in recv(). Bye Bye" << endl;
                break;
            }
            if (byteReceived == 0)
            {
                time_t tm = time(NULL);
                cout << "Client " << host << " " << service << " disconnected" << " at " << ctime(&tm) << endl;
                break;
            }
            cout << string(buf, 0, byteReceived) << endl;
            send(clientSocket, buf, byteReceived + 1, 0);
        
        }
 
    closesocket(clientSocket);
    WSACleanup();
    system("pause");
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.04.2020, 14:43
Ответы с готовыми решениями:

Написать соединение: много клиентов - сервер (Winsock; на сервере 3 сокета: 2 TCP и 1 UDP)
Всем здрасьте !!!! Мне надо написать соединение: много клиентов - сервер Тут мне надо иметь на сервере 3 сокета: 2 TCP и 1 UDP ...

Взаимодействие клиентов между собой на Tcp сервере
Подключенных клиентов держу в списке. Нужно чтобы 2 клиента могли общаться между собой. Как это сделать ?

Соединение нескольких клиентов с одним сервером TCP
Как реализовать такое: сначала к серверу подключается первый клиент TCP - передает данные. Но если в момент передачи данных первым клиентом...

4
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
25.04.2020, 22:31
Цитата Сообщение от Vlad_b Посмотреть сообщение
Сколько ни пытался и не смотрел разные гайды и сайты, так и не понял как привести свой эхо сервер под несколько клиентов. Помогите, что и где нужно добавить.
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
inline
int SockVerify(int err)
{
    if (err == SOCKET_ERROR)
        std::cout << "ERROR: " << ::WSAGetLastError();
 
    return err;
}
 
void SimpleEchoServer(u_short port)
{
    char buf[1024];
    std::vector<WSAPOLLFD> fds;
    fds.push_back({::socket(AF_INET, SOCK_STREAM, 0), POLLIN, 0});
    
    sockaddr_in addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);
    
    SockVerify(::bind(fds[0].fd, (const sockaddr *)&addr, sizeof(addr)));
    SockVerify(::listen(fds[0].fd, SOMAXCONN));
    std::cout << "Listen: " << port << std::endl;
    while (!_kbhit())
    {
        int res = SockVerify(::WSAPoll(fds.data(), ULONG(fds.size()), 100));
        if (res < 0)
            break;
 
        if (!res)
            continue;
 
        if (fds[0].revents == POLLRDNORM)
        {
            sockaddr_in addr = { 0 };
            socklen_t len = sizeof(addr);
            SOCKET sock = ::accept(fds[0].fd, (sockaddr *)&addr, &len);
            std::cout << "Accept" << std::endl;
            fds.push_back({sock, POLLIN, 0});
            --res;
        }
 
        for (size_t i = 1; res > 0 && i < fds.size(); )
        {
            if (fds[i].revents == 0)
            {
                ++i;
                continue;
            }
 
            if (fds[i].revents != POLLRDNORM)
            {
                std::cout << "Disconnect #" << i << std::endl;
                ::closesocket(fds[i].fd);
                fds.erase(fds.begin() + i);
            }
            else if (const auto n = SockVerify(recv(fds[i].fd, buf, int(std::size(buf)), 0)); n == 0)
            {
                std::cout << "Connection closed, #" << i << std::endl;
                ::closesocket(fds[i].fd);
                fds.erase(fds.begin() + i);
            }
            else
            {
                std::cout << "Recv #" << i << ": " << n << std::endl;
                SockVerify(::send(fds[i].fd, buf, n, 0));
                ++i;
            }
 
            --res;
        }
    }
 
    for (auto &item: fds)
        ::closesocket(item.fd);
}
0
26.04.2020, 12:10

Не по теме:

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
::WSAPoll
тут люди советуют не использовать WSAPoll.

0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.04.2020, 12:17
Цитата Сообщение от GbaLog- Посмотреть сообщение
тут люди советуют не использовать WSAPoll.
8 лет назад, потому что на Windows Vista плохо работает и отсутствует в более ранних версиях?
0
26.04.2020, 15:28

Не по теме:

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
8 лет назад
если вы заметили, то microsoft пометила проблему как "won't fix".
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
потому что на Windows Vista плохо работает
а вы думаете, что на Win7/8/8.1/10 она по-другому реализована?
особенно учитывая то, что они отказались её фиксить.

вообще, особенного в ней ничего нет и она работает.
да и баг в ней, как по мне, незначительный.
только вот почему-то её действительно не используют и даже есть некоторые наблюдения,
говорящие о том, что она медленнее обычного select'a работает в некоторых тестах.
https://github.com/zeromq/libzmq/issues/2805

я не предлагаю вам её не использовать, просто делюсь информацией.

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

(Winsock) Сервер - Несколько клиентов
В msdn есть пример создания сервера, который принимает 1 соединение. Не могу врубиться, как сделать, чтобы к серваку подключалось...

winsock - принять несколько клиентов, (не получается)
winsock - принять несколько клиентов, (не получается) добрый день, никак не могу принять несколько клиентов на сервер. принимается только...

Обслуживание клиентов [Winsock | dos attack]
Описание принятия клиента: static void ReceiveClient(void* param) { oriPacket *buf = new oriPacket;

WinSock tcp client/server
Может у кого то есть пример простой реализации client/server на winsock ? неважно на каком языке. Мне надо что бы сервер отправлял...

TCP-эхо клиент-сервер (WinSock)
Здравствуйте! Подскажите, пожалуйста, почему TCP-эхо клиент-сервер неправильно работает? Сервер отправляет клиенту правильно только первую...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru