Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202

Сервер - клиент не коннектится

21.04.2015, 20:00. Показов 1234. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу изучить сети, первое что хотелось бы реализовать - простейший онлайн чат. Взял первый попавшийся исходник, подлатал как мне удобно.
Скомпилировал, проверил, написал с клиента сообщение серверу и обратно - все работает замечательно, как надо.
Тут я захотел конечно же скинуть клиент другу из Украины и проверить работоспособность клиента на всякий случай, не вышло нечего, ip верный, порт верный, скинул другу из России - та же беда. Тут я понял что не все так просто как хотелось бы. Начинать с чего нужно и поэтому прошу объяснить в теории хотя бы, грамотных людей по этому вопросу.
Исходный код клиента и сервера прилагаю.
Сервер:
Кликните здесь для просмотра всего текста
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
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// Пример простого TCP – эхо сервера
 
#include "stdafx.h"
#include < iostream >
#pragma comment( lib, "ws2_32.lib" )
#include < Windows.h >
#include < conio.h >
using namespace std;
 
  #define MY_PORT    666 // Порт, который слушает сервер
 
 // заведём глобальную переменную  ниже для обмена данным между нитями сервера   
char* cbuff= "common buffer"; // общий буфер для записи сообщений от всех клиентов
            
 
  // макрос для печати количества активных
  // пользователей 
  #define PRINTNUSERS if (nclients)\
  printf("%d user on-line\n",nclients);\
  else printf("No User on line\n");
 
  // прототип функции, обслуживающий
  // подключившихся пользователей
  DWORD WINAPI WorkWithClient(LPVOID client_socket);
 
  //будет просто циклически проверять знкачение глобальной переменной
  DWORD WINAPI CheckCommonBuffer(LPVOID client_socket); 
 
  // глобальная переменная – количество
  // активных пользователей 
  int nclients = 0;
 
  int main(int argc, char* argv[])
  {
    char buff[1024];    // Буфер для различных нужд
 
    printf("TCP SERVER DEMO\n");
 
    // Шаг 1 - Инициализация Библиотеки Сокетов
    // Т.к. возвращенная функцией информация
    // не используется ей передается указатель на
    // рабочий буфер, преобразуемый
    // к указателю  на структуру WSADATA.
    // Такой прием позволяет сэкономить одну
    // переменную, однако, буфер должен быть не менее
    // полкилобайта размером (структура WSADATA
    // занимает 400 байт)
    if (WSAStartup(0x0202,(WSADATA *) &buff[0])) 
    {
      // Ошибка!
          printf("Error WSAStartup %d\n",
             WSAGetLastError());
      return -1;
    }
 
    // Шаг 2 - создание сокета
    SOCKET mysocket;
    // AF_INET     - сокет Интернета
    // SOCK_STREAM  - потоковый сокет (с
    //      установкой соединения)
    // 0      - по умолчанию выбирается TCP протокол
    if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
      // Ошибка!
      printf("Error socket %d\n",WSAGetLastError());
      WSACleanup();
        // Деиницилизация библиотеки Winsock
      return -1;
    }
 
    // Шаг 3 связывание сокета с локальным адресом
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
             // не забываем о сетевом порядке!!!
    local_addr.sin_addr.s_addr=0;
             // сервер принимает подключения
             // на все IP-адреса
 
    // вызываем bind для связывания
    if (bind(mysocket,(sockaddr *) &local_addr,
                sizeof(local_addr)))
    {
      // Ошибка
      printf("Error bind %d\n",WSAGetLastError());
      closesocket(mysocket);  // закрываем сокет!
      WSACleanup();
      return -1;
    }
 
    // Шаг 4 ожидание подключений
    // размер очереди – 0x100
    if (listen(mysocket, 20))
    {
      // Ошибка
      printf("Error listen %d\n",WSAGetLastError());
      closesocket(mysocket);
      WSACleanup();
      return -1;
    }
 
    printf("Waiting for connection\n");
 
    // Шаг 5 извлекаем сообщение из очереди
    SOCKET client_socket;    // сокет для клиента
    sockaddr_in client_addr;    // адрес клиента
              // (заполняется системой)
 
    // функции accept необходимо передать размер
    // структуры
    int client_addr_size=sizeof(client_addr);
 
    // цикл извлечения запросов на подключение из
    // очереди
    /* accept - держит управление и не даёт циклу вращаться
    (то есть не даёт потоку- нити выполняться вообще)
    пока не поступит очередной запрос на соединение*/
    while((client_socket = accept(mysocket, (sockaddr *)
            &client_addr, &client_addr_size)))
    {
      nclients++;      // увеличиваем счетчик
              // подключившихся клиентов
 
      // пытаемся получить имя хоста
      HOSTENT *hst;
      hst=gethostbyaddr((char *)
          &client_addr.sin_addr.s_addr,4, AF_INET);
 
      // вывод сведений о клиенте
      printf("+%s [%s] new connect!\n",
      (hst)?hst->h_name:"",
      inet_ntoa(client_addr.sin_addr));
      PRINTNUSERS
 
      // Вызов нового потока для обслужвания клиента
      // Да, для этого рекомендуется использовать
      // _beginthreadex но, поскольку никаких вызов
      // функций стандартной Си библиотеки поток не
      // делает, можно обойтись и CreateThread
      DWORD thID;
      CreateThread(NULL,NULL,WorkWithClient,
              &client_socket,NULL,&thID);
 
        /* запускаем функции прослушивания чужих сообщений
        нам нужен именно отдельный поток, потому что recv()
        забирает управление и не позволит послать клиенту 
        сообщение пока от этого самого ("родного" для данной
        нити сервера) клиента что-нибудь не придёт */
      // CreateThread(NULL,NULL, CheckCommonBuffer, &client_socket,NULL,&thID);
    }
    return 0;
  }
 
 
 
  // Эта функция создается в отдельном потоке и
  // обсуживает очередного подключившегося клиента
  // независимо от остальных
  DWORD WINAPI WorkWithClient(LPVOID client_socket)
  {
    SOCKET my_sock;
    my_sock=((SOCKET *) client_socket)[0];
    char buff[1024] = "123124";
//  char buff2[20*1024];
    #define sHELLO "Hello, new member! This's our win socket chat!))\r\n"
     //printf(" \n new thread is started connect!\n");
 
    // отправляем клиенту приветствие 
    send(my_sock, sHELLO, sizeof(sHELLO), 0);
 
     
     
    // цикл эхо-сервера: прием строки от клиента и
       int bytes_recv;
    // возвращение ее клиенту
   // while ( (bytes_recv=recv(my_sock,&buff[0],sizeof(buff),0)) && (bytes_recv !=SOCKET_ERROR))
     while (1)
     {
        bytes_recv = recv(my_sock,buff,sizeof(buff),0);
        cbuff = buff; // пишем в глобальную переменную чтобы другие участники
        // узнали о сообщении
        send(my_sock,&buff[0],bytes_recv,0);
     
 
        /*давайте организуем в консоли сервера общий чат-
        будем выводить туда все сообщение приходящие отразных клиентов-
        для этого просто используем printf*/
        cout << buff << std::endl; // печатает сообщения всех клиентов в консоли сервера
     }
 
    // если мы здесь, то произошел выход из цикла по
    // причине возращения функцией recv ошибки –
    // соединение клиентом разорвано
    nclients--; // уменьшаем счетчик активных клиентов
    printf("-disconnect\n"); PRINTNUSERS
 
    // закрываем сокет
    closesocket(my_sock);
    return 0;
  }
 
  /*эту функцию надо допилить так как есть проблемы 
  с передаваемым и принимаемы м размерами буфера*/
  DWORD WINAPI CheckCommonBuffer(LPVOID client_socket)
  {
 
    SOCKET my_sock;
    my_sock=((SOCKET *) client_socket)[0];
    char buf[1024]; // для контроля размерности буфера
    while (1)
    {
        /* изменение этого значения - признак того, что пришло новое сообщение
                           buff является глобальной и поправить её может любая нить сервера -
                           просто проверяем значение первого байта(это не слишком надёжный способ)*/
        if (cbuff[0] != 9) 
 
        { 
            //char buf[1024] =cbuff ;
            send(my_sock, cbuff, sizeof(cbuff), 0);
            cbuff[0] = 9;
            //Sleep(2000);
        }
        /*давайте организуем в консоли сервера общий чат-
        будем выводить туда все сообщение приходящие отразных клиентов-
        для этого просто используем printf*/
        //cout << buff << std::endl; // печатает сообщения всех клиентов в консоли сервера
    }
  }

Клиент:
Кликните здесь для просмотра всего текста
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
128
129
130
131
132
133
// Пример простого TCP клиента
#include "stdafx.h"
#include < iostream >
#pragma comment( lib, "ws2_32.lib" )
#include < Windows.h >
#include < conio.h >
 
 
  #define PORT 666
  #define SERVERADDR "127.0.0.1"
 
DWORD WINAPI GetNewMessage(LPVOID client_socket); 
 
  int main(int argc, char* argv[])
  {
    char buff[1024];
    printf("TCP DEMO CLIENT\n");
 
    // Шаг 1 - инициализация библиотеки Winsock
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
      printf("WSAStart error %d\n",WSAGetLastError());
      return -1;
    }
 
    // Шаг 2 - создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock < 0)
    {
      printf("Socket() error %d\n",WSAGetLastError());
      return -1;
    }
 
    // Шаг 3 - установка соединения
 
    // заполнение структуры sockaddr_in
    // указание адреса и порта сервера
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;
 
    // преобразование IP адреса из символьного в
    // сетевой формат
    if (inet_addr(SERVERADDR)!=INADDR_NONE)
      dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
      // попытка получить IP адрес по доменному
      // имени сервера
      if (hst=gethostbyname(SERVERADDR))
      // hst->h_addr_list содержит не массив адресов,
      // а массив указателей на адреса
      ((unsigned long *)&dest_addr.sin_addr)[0]=
        ((unsigned long **)hst->h_addr_list)[0][0];
      else
      {
        printf("Invalid address %s\n",SERVERADDR);
        closesocket(my_sock);
        WSACleanup();
        return -1;
      }
 
    // адрес сервера получен – пытаемся установить
    // соединение 
    if (connect(my_sock,(sockaddr *)&dest_addr,
                sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
      return -1;
    }
 
    printf("Соединение с %s успешно установлено\n\
    Type quit for quit\n\n",SERVERADDR);
      
    DWORD thID;
    //CreateThread(NULL, NULL, GetNewMessage, &my_sock, NULL, &thID);
 
    // Шаг 4 - чтение и передача сообщений
    int nsize;
    while((nsize = recv(my_sock,&buff[0], sizeof(buff)-1,0)) !=SOCKET_ERROR)
    {
      // ставим завершающий ноль в конце строки 
      buff[nsize]=0;
 
      // выводим на экран 
      printf("S=>C:%s",buff);
 
      // читаем пользовательский ввод с клавиатуры
      printf("S<=C:"); fgets(&buff[0],sizeof(buff)-1, stdin);
 
      // проверка на "quit"
      if (!strcmp(&buff[0],"quit\n"))
      {
        // Корректный выход
        printf("Exit...");
        closesocket(my_sock);
        WSACleanup();
        return 0;
      }
 
      // передаем строку клиента серверу
      send(my_sock,&buff[0],nsize,0);
    }
 
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return -1;
  }
 
 
  /* эту функцию надо использовать если запущена
  CheckCommonBuffer() на сервере*/
DWORD WINAPI GetNewMessage(LPVOID client_socket)
  {
 
    SOCKET my_sock;
    my_sock=((SOCKET *) client_socket)[0];
    int nsize;
    char buff[1024];
 
 while((nsize = recv(my_sock, &buff[0], sizeof(buff)-1,0)) !=SOCKET_ERROR)
    {
      
        // ставим завершающий ноль в конце строки 
      buff[nsize]=0;
 
      // выводим на экран 
      printf("S=>C:%s",buff);
    }
 return 0;
  }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.04.2015, 20:00
Ответы с готовыми решениями:

Клиент-Серверное приложение. Как сделать, чтобы сервер сам отправлял сообщения на клиент
Добрый день всем. Проблема заключается в следующем: Есть клиент-серверное приложение, хочу реализовать своего рода защиту, чтобы при...

Tcp ip клиент-сервер C++ сервер выводит мусор
server # include &lt;sys/types.h&gt; # include &lt;iostream&gt; # include &lt;winsock2.h&gt; # include &lt;stdlib.h&gt; # pragma comment (lib,...

Клиент/сервер: клиент посылает серверу слово; определить, является ли это слово палиндромом
Осуществить взаимодействие клиента и сервера на основе протокола TCP/IP. Функционирование клиента и сервера реализовать следующим образом:...

6
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
21.04.2015, 21:22
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
#define SERVERADDR "127.0.0.1"
ДЕСАНТУРА, у вас клиент коннектится к localhost.
0
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
21.04.2015, 21:29  [ТС]
нет, это в примере кода просто, у меня прописан верный ip, вписывал и ip который выдает модем и ip который выдает сайт "2ip", я просто догадываюсь что, вот так вот просто чатиться с другим человеком из другой страны не вариант, тут же пока клиент до тебя доконнектится пройдет кучу масок, подмасок, маршрутезаторов и роутеров + у меня не статический ip. Хотелось бы уточнить на что нужно обратить внимание, чтобы создать такой чат, что нужно понимать и изучить, хотя бы в теории
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
21.04.2015, 21:52
ДЕСАНТУРА, чтобы забиндить серверный сокет и чтобы он был доступен через интернет нужен белый IP, у вас скорее всего серый IP (В чем отличие "белого" и "серого" IP-адреса?).

Добавлено через 3 минуты
ДЕСАНТУРА, у провайдеров обычно выделенный публичный IP-адрес это отдельная платная услуга.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
21.04.2015, 22:07  [ТС]
Хорошо, если я куплю статический адрес, 200 рублей - это не проблема - смогу ли я забиндится после этого или есть еще нюансы?
0
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
21.04.2015, 22:17
ДЕСАНТУРА, по идее никаких больше проблем быть не должно, но лучше уточнить у вашего провайдера - какие порты на вашей машине с белым IP будут открыты. Впринципе, может быть такой вариант, что провайдер откроет только ограниченное кол-во портов, например 80 и 443.

Если ваш чат работает в localhost, то с большой вероятностью он сможет работать и через интернет при наличии белого IP у сервера. Сетевые приложения легче всего разрабатывать и тестировать под виртуальными машинами (virtualbox, например), настроив виртуальную сеть между ними.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
21.04.2015, 22:27  [ТС]
спасибо понял, надеюсь это единственная проблема при коннекте
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.04.2015, 22:27
Помогаю со студенческими работами здесь

Клиент и сервер
Здравствуйте, понимаю что тема уже не раз поднималась, но... В сервере функция accept видает ошибку. ws2_32.lib подключен. Код сервера:...

Клиент - сервер
Здравствуйте! У меня возникла проблема с &quot;клиент сервер&quot; программой . Не могу найти пример . Киньте пожалуйста сюда , только мне...

Клиент-Сервер
Здравствуйте форумчане! Нужна помощь в написании клиент-серверной программы. Суть её такая, клиенты стучатся на один порт сервера и сервер...

КЛИЕНТ-СЕРВЕР
Попробовала изменить сервер следующим образом: #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #include...

Клиент-сервер
Здравствуйте, пишу маленький проект, сервер на ++, клиент на шарпах, и падает сервер, не могу понять почему, помогите плиз. #include...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера 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. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru