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

Socket: Client & Server

11.05.2010, 22:15. Показов 16180. Ответов 86
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужен квалифицированный совет!
Существует устройство, на котором стоит ОС Linux.
Это устройство соединено с ПК с Win.
Это устройство с ОС Линукс должно отдавать постоянно данные на ПК, но при помощи приложения на ПК оно еще должно управляться.
Используя сокеты, написан сервер на "С" под Линукс и Клиент на "С++" под Win на ПК. Но чувствую что этого недостаточно.
Как я понял, сервер не может осуществлять постоянную передачу данных, кроме ответных сообщений на запрос от клиента. Если не прав - поправьте меня.
Т.е., как я догадываюсь, нужно реализовывать на обоих машинах и сервер и клиент? Клиент под Линукс нужен чтобы постоянно отправлять данные от устройства серверу на ПК, а сервер ПК будет подтверждать прием данных, сервер под линукс нужен чтобы принимать запросы от клиента из Win (ПК) на упраление (изменение параметров устройства).
Правильные мысли? Или можно сделать проще?
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.05.2010, 22:15
Ответы с готовыми решениями:

FTP-client на Socket API
Здравствуйте. Решил написать простенький FTP-клиент, всё получилось, кроме команды RETR. При получении файла приходит больше байт, чем...

Local chat, C++ server JAVA client
Хочу написать локальный чат чтобы серверная часть была на C++ а клиентская на JAVA. По какой то причине JAVA не может принимать сообщения...

Server&Client Socket, ошибка подключения
При подключении к серверу вылетает ошибка 10060,10049,10061 У меня Win7 но если сервер будет на WinXP то подключается. В чём прикол?

86
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.05.2010, 22:21
Зачем. Создаёте сервер на одной стороне. С другой подключитесь к нему. и общайтесь. Не знаю про UNIX-сокеты (только начал с ними), но в WinSock2 функции recv() и send() запрашивают дескриптор сокета, по которому установлено соединение. То есть по однократно установленному соединению можно и отправлять, и принимать пакеты.

Но!

Можно либо ждать пакета, либо отправлять пакеты. Поэтому в двух разных потоках (см. _beginthread) нужно установить два соединения. Сначала одно, а потом, после установки первого - второе. И обязательно убедиться на сервере, что оба соединения установлены с одним и тем же клиентом! А затем по одному соединению сервер будет выводить - клиент вводить, а по другому - наоборот.

Я сам застрял на программировании сокетов с этой многопоточностью. Так что сначала - к ней.
1
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
11.05.2010, 22:29  [ТС]
Цитата Сообщение от talis Посмотреть сообщение
Сначала одно, а потом, после установки первого - второе.
Буду думать как реализовать многопоточность на "С". Если есть материал - буду рад..
Т.е. получается эти 2 потока на сервере должны быть синхронизированы? Как на "С" синхронить? в билдере использовал критические секции.
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.05.2010, 22:49
По поводу многопоточности - посмотрите _beginthread. Не знаю на счёт UNIX, в Windows работает.
Если потоки получают доступ к общим объектам - да, они должны быть синхронизированы. В C нет такого понятия, как критические секции, просто по тому, что в C нет встроенной многопоточности (это всё-таки универсальный язык!). Критические секции - это спецификация Windows. В Windows-клиенте можете использовать их. Для Linux слышал о библиотеке boost, в ней были объекты mutex'ы. Только не знаю, сишная ли она. Вроде нет, но поискать стоит. Так же поищите информацию по pthread.h - тоже для Linux.


--- ДОБАВЛЕНО:

pthread.h должен вас устроить. Есть и реализация для Win32. Читайте wikipedia. Попробуйте также английскую.
1
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 10:55  [ТС]
Хорошо, как я понял идея следующая:
сервер размещаю на машине, где стоит линукс, создаю 2 потока, которые постоянно должны крутиться.
Один отвечает за отправку данных клиенту, а второй за прием команд от клиента.
А со стороны клиента как сделать так, чтобы одновременно получать данные от сервера и отправлять команды? тоже 2 потока?
Немного не ясно... Хэлп.
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.05.2010, 11:30
Я себе это так представляю:

Схема связи:
Code
1
2
3
4
5
6
7
8
 поток 1      поток 2
              
          КЛИЕНТ
        OUT      IN
         |         ^
         v         |
        IN       OUT
          СЕРВЕР
Установка соединения:

Сервер создаёт первый поток и прослушивает порт 41000
Клиент создаёт первый поток и подключается к серверу по 123.45.76.89:41000
Сервер отправляет клиенту сучайный код, скажем 0x21f1
Клиент возвращает его серверу
Первое соединение установлено
Сервер создаёт второй поток, прослушивает порт 41001
Клиент создаёт второй поток и в нём подключается к 123.45.76.89:41001
Клиент отправляет сервер 0x21f1 (то, что отправил ему сервер в первом соединении)
Сервер таким образом убеждается, что соединился с правильным клиентом
Второе соединение установлено

Ну и вперёд...
2
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 12:03  [ТС]
Вопрос:

на сервере использую функцию извлечения запроса accept, но она похоже является блокирующей, пока никакого соединения от клиента не случилось, указатель дальше не продвинется... а как сделать, чтобы отсутствовала блокировка, а просто выводился флаг, что ничего от клиента не поступило, и указатель продвинулся дальше?
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.05.2010, 12:09
Мне такой способ не знаком. Возможно, асинхронные сокеты, но я с ними не работал. А чем вас не устраивает блокировка? С ней вы гарантированно получите пакет сразу, как только он придёт от клиента. К тому же вывод осуществляется в соседнем потоке, параллельно. Если у вас есть ещё рабочие задачи, выполняйте их в потоке вывода, либо выделите ещё один поток, в котором их выполняйте. А эти два оставьте на ввод-вывод.
1
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 17:02  [ТС]
Пытаюсь отладить простейший механизм, но сообщение на сервер приходят начиная со второй отправки, т.е. первый раз отправил, на сервер ничего не пришло, при второй отправке на сервер поступает первое сообщение, почему так?
Вот код сервера:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
WSADATA WsaData;
WSAStartup(0x202, &WsaData)
gethostname(hostname, sizeof(hostname)
gethostbyname(hostname)
socket(AF_INET, SOCK_STREAM, 0)
setsockopt(sock1, SOL_SOCKET, SO_SNDBUF, optval_set_sndbuf, optlen_set_sndbuf)
setsockopt(sock1, SOL_SOCKET, SO_RCVBUF, optval_set_rcvbuf, optlen_set_rcvbuf)
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
bind(sock1, (struct sockaddr FAR *)&sin, sizeof(sin))
listen(sock1, 3)
answer_len = sizeof(client)
sock2 = accept(sock1, (struct sockaddr FAR *)&client, &answer_len))
sent_bytes = send(sock2, SERVER_MSG, sizeof(SERVER_MSG), 0)
while (1)
{
    recvs(sock2, buffer, &len)      
}
shutdown(sock2, SD_SEND)
closesocket(sock2)
WSACleanup()
Может где-то накосячил? Или быть может код клиента проблемный?
ps. Считаем что все функции выше while выполнены без ошибок.
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
12.05.2010, 17:13
Цитата Сообщение от sitesv Посмотреть сообщение
ps. Считаем что все функции выше while выполнены без ошибок.
тут должна быть четкая последовательность. протокол.
если одна стороная отправила сообщение, вторая обязательно должна принять.
так что, надо бы код и сервера и клиента.

а код сервака честно говоря страшный оО
0
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 21:21  [ТС]
Код клиента:
1. Сначала нажимаю на клавишу соединения.
2. Потом жму на клавишу отправки сообщения


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
void __fastcall TForm1::Button3Click(TObject *Sender) //СОЕДИНЕНИЕ С СЕРВЕРОМ
{
        prep()
        connect_to_serv()        
}
bool prep()
{
    WSADATA WsaData;
    WSAStartup(0x202, &WsaData)
    gethostname(hostname, sizeof(hostname))
        myhost = gethostbyname(hostname))
        sock = socket(AF_INET, SOCK_STREAM, 0)
        setsockopt(sock, SOL_SOCKET, SO_SNDBUF, optval_set_sndbuf, optlen_set_sndbuf)
        setsockopt(sock, SOL_SOCKET, SO_RCVBUF, optval_set_rcvbuf, optlen_set_rcvbuf)
        client.sin_family      = AF_INET;
        client.sin_addr.s_addr = INADDR_ANY;
        client.sin_port        = htons(CLIENT_PORT);
    h = gethostbyname(server_name)
        server.sin_family = AF_INET;
        memcpy((char *)&server.sin_addr, h -> h_addr, h -> h_length);
    server.sin_port = htons(SERVER_PORT);
}
bool connect_to_serv()
{
        answer_len=0;
        while (connect(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
        {
                Sleep(1);
        }
        recv(sock, buffer, BUF_SIZE, 0)
}
void __fastcall TForm1::Button2Click(TObject *Sender)  //ОТПРАВКА СООБЩЕНИЯ
{
    sends(sock, message, &len); 
}
Добавлено через 3 часа 21 минуту
fasked, ну как, есть мысли?

Добавлено через 37 минут
нааарод, помогай))
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
12.05.2010, 21:28
sitesv, не нужно мудрить с двумя потоками. Достаточно одного TCP-соединения. Клиент и сервер - понятия условные: сервер создаёт соединение, а клиент к нему прицепляется. В дальнейшем конкретно в данном случае обе стороны соединения могут быть равноправными: обе отправляют и принимают данные. Грубо говоря, как irc - события могут возникать как на клиентской стороне, так и на стороне сервера
1
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 21:31  [ТС]
Evg, хорошо, учту, но тут для начала я решил написать что-то простенькое, так сказать основу, которую вдальнейшем можно использовать, на 1й странице есть код сервера, на 2й - код клиента, когда отправляю на сервер запрос, recv принимает эти данные только при повторной отправки на клавишу отправки сообщения, т.е. получается, что сервер принимает данные с "задержкой", видимо в коде что-то не в порядке, пока еще не смог разобраться в чем причина... может будут мысли - буду признателен.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
12.05.2010, 21:43
Я уже несколько лет, как с сетевыми задачами не работал, так что глядя только на код в воздухе ничего сказать не могу. Пример простенького сервера под линух с небольшим описанием можно посмотреть здесь Грамотная реализация клиент-серверного приложения (посты #9 и #10)
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.05.2010, 23:39
Если у вас устройство ждёт сообщения с компьютера, реагирует на него либо отправкой какого-либо ответа, либо действием, то тогда согласен, многопоточность здесь ни к месту. Но если устройство может по своей инициативе что-то отправить компьютеру, а компьютер - устройству - тогда либо многопоточность, либо неблокирующиеся сокеты. Но я с ними не работал, тут ничем помочь не смогу.
1
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
12.05.2010, 23:45  [ТС]
Можно при однократном создании сокета и инициализации адреса и порта, дальше многократно использзовать операторы отправки и приема?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
12.05.2010, 23:50
Цитата Сообщение от sitesv Посмотреть сообщение
Можно при однократном создании сокета и инициализации адреса и порта, дальше многократно использзовать операторы отправки и приема?
Можно. Т.е. на виндовой машине, к примеру, программа будет 1 секунду ожидать приёма на сокете, а потом 1 секунду опрашивать устройство
0
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
13.05.2010, 09:28  [ТС]
А если изначально неизвестно как построен сервер, известен только его адрес и порт, то зависит ли повторная инициализация сокета итд на клиенте от этого?
Взял пример с сайта http://club.shelek.ru/viewart.php?id=37.
Пытаюсь повторно использовать операторы send, а потом receive, но выдается ошибкА, что длина данных нулевая... быть может сервер закрывает соединение после однократного обращения?

Добавлено через 7 часов 45 минут
есть мысли?

Добавлено через 1 час 47 минут
есть мысли?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
13.05.2010, 10:25
Цитата Сообщение от sitesv Посмотреть сообщение
есть мысли?
Весь форум с утра и до вечера занят только тем, что думают, как бы разобраться с твоей проблемой
0
27 / 25 / 5
Регистрация: 22.04.2010
Сообщений: 772
13.05.2010, 10:42  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Весь форум с утра и до вечера занят только тем, что думают, как бы разобраться с твоей проблемой
Спасибо за насыщенный ответ.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.05.2010, 10:42
Помогаю со студенческими работами здесь

Nodejs net socket server and android socket client
Добрый день Форумчане нужно помощь гуру! Решил с другом написать сервер на ноде с использование сокетов и андроид клиент отправки сокет. Но...

Windows socket server python + socket client js
Здравствуйте пытаюсь решить такую задачу, на веб странице реализовал soket клиент на js, и socket server, сокет сервер получает данные от...

Socket Android Client and Java Socket Server
Доброго времени суток.Пытаюсь сделать простое клиент-серверное приложение. Клиент - приложение на Android устройстве. Сервер - Приложение...

Server(Client)Socket
Всем привет. Собираюсь сделать передачу команд между сервером-клиентом через socket'ы, но возник один вопрос: будут ли проблемы с...

Socket Server, Client
Доброго времени суток. Решил разобраться с сокетами. Но почему-то сообщения не приходят... Клиент: messsage = "Test"; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера 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