Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/116: Рейтинг темы: голосов - 116, средняя оценка - 4.72
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
1

Грамотная реализация клиент-серверного приложения

10.05.2009, 21:40. Показов 22590. Ответов 31
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Возник вопрос как грамотно реализовать клиент-серверное приложение под Linux'ом. Пока имеется стандартная реализация через потоковые сокеты. Но при некорректном завершении работы клиента сервер подвисает и умирает для внешних запросов. Здесь смысл почему так происходит понятен. Необходимо реализовать грамотную реализацию для устранения этой проблеммы. Слышал про не блокирующие сокеты. Но в эту сторону не хочу копать. Хочется реализовать с помощью процессов либо потоков. Вроде как с помощью функции fork можно делать при каждом запросе копию процесса и работать с каждым запросом в индивидуальном процессе. Либо можно реализовать с помощью потоков. Слышал, что понятие потоков и процессов в linux'е отличается от винды. Вот хочу дельный совет куда начать копать, чтобы не ошибиться маршрутом. Хочется реализовать грамотно и не сложно)). Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.05.2009, 21:40
Ответы с готовыми решениями:

Прокомментировать код клиент-серверного приложения
Помогите в этом разобраться. Можете написать комментарии к коду пожалуйста Клиент ...

Реализация клиент-серверного соединения
Реализовать клиент-серверного соединения на основе протокола TCP. Клиентская часть должна...

Реализация клиент-серверного взаимодействия на C#
Кто может поделится ссылкой на пример приложения на C#, 1-клиент(делает запросы в БД получает ответ...

Реализация клиент-серверного взаимодействия
Привет. Нужна помощь, необходимо написать клиент-сервер, в котором реализовать следующие...

31
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
15.03.2010, 20:44 21
Author24 — интернет-сервис помощи студентам
kirjushyk, ну и чем твой ответ отличается от -
Цитата Сообщение от malik555 Посмотреть сообщение
Автору в помощь
#include <pthread.h> там есть все что тебе нужно .
?
0
60 / 22 / 2
Регистрация: 13.03.2010
Сообщений: 65
15.03.2010, 22:02 22
Не заметил =)
0
4 / 4 / 0
Регистрация: 26.03.2010
Сообщений: 28
26.03.2010, 11:34 23
Решил сделать несколько простеньких сетевых игрушек типа морской бой, шашки и т.д.
Так вот возник вопрос как правильно сделать.
Создавать поток на каждое соединение или в цикле по очереди слушать каждый сокет?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2010, 11:39 24
Для начала сделай по простому, т.е. БЕЗ потоков. Внешне это будет подтормаживать, но зато хотя бы как-то поймёшь, как реализовывается сетевая часть, не вникая в премудрости работы с несколькими потоками. А потом можно работать с потоками
0
4 / 4 / 0
Регистрация: 26.03.2010
Сообщений: 28
26.03.2010, 14:20 25
Ну вот взял пример с неблокирующими сокетами и начал смотря на код делать )
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
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <set>
#include <algorithm>
#include <sys/time.h>
 
using namespace std;
 
static sockaddr_in addr;
static void sockInit();
static void sockProcess();
static set<int> clients;
static int listener;
 
int main (){
    sockInit();
    sockProcess();
}
 
void sockInit(){
    listener = socket(AF_INET,SOCK_STREAM,0);
    if(listener<0){
    printf("Error: socket\n");
    }
    fcntl(listener,F_SETFL,O_NONBLOCK);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(listener,(struct sockaddr *)&addr,sizeof(addr))<0){
    printf("Error: bind\n");
    }
    listen(listener,2);
    clients.clear();
}
 
void sockProcess(){
    while (true){
    fd_set readset;
    FD_ZERO(&readset);
    FD_SET(listener,&readset);
 
    for(set<int>::iterator it = clients.begin(); it != clients.end(); it++){
        FD_SET(*it, &readset);
    }
 
    timeval timeout;
    timeout.tv_sec=15;
    timeout.tv_usec=0;
 
    int mx = max(listener, *max_element(clients.begin(),clients.end()));
    if(select(mx+1,&readset,NULL,NULL,&timeout <= 0)){
        printf("Error: select\n");
    }
 
    if(FD_ISSET(listener,&readset)){
        int sock = accept(listener,NULL,NULL);
        if(sock < 0){
        printf("Error: accepr\n");
        }
        fcntl(sock,F_SETFL,O_NONBLOCK);
        clients.insert(sock);
        printf("Connection\n");
    }
    }
}
запускаю, пытаюсь подключится по телнету, и как только жму подключится постоянно начинает бежать строка Connection
Я так понимаю Listener - это здесь получает нового клиента и его можно сделать блокирующим и разместить в одном потоке, а уже sock делать неблокирующим и всех клиентов разместить в другом?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2010, 14:50 26
У меня твой код работает. Во всяком случае telnet к нему приконнектился

Код
$ telnet 127.0.0.1 3425
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Ты как telnet запускаешь?

Добавлено через 46 секунд
Правда сервер всё время пишет "Error: select"

Добавлено через 1 минуту
Неудивительно - ты условие <=0 затащил вовнутрь последнего параметра select'а
1
4 / 4 / 0
Регистрация: 26.03.2010
Сообщений: 28
26.03.2010, 15:11 27
Да, точно сейчас нормально подключился. Спасибо! Буду дальше разбираться.
0
4 / 4 / 0
Регистрация: 26.03.2010
Сообщений: 28
18.06.2010, 01:01 28
Подскажите, ну например я использую неблокирующие сокеты, как реализовать принятие и отправку данных?
Код
for(set<int>::iterator it = clients.begin(); it != clients.end(); it++)
        {
            if(FD_ISSET(*it, &readset))
            {
                bytes_read = recv(*it, buf, 1024, 0);
                if(bytes_read <= 0)
                {
                    close(*it);
                    clients.erase(*it);
                    continue;
                }
            }
        }
не совсем понимаю как реализовать обмен между клиентами, например данные я тут приму, а как потом отправить ответ? за раз данные могут не отправится по идее, а если отправятся то будет большая задержка. Делал раньше на java но я делал каждого клиента в отдельном потоке, но прочёл что это не хорошо если много клиентов
0
Dimrix
20.09.2010, 14:52 29
Цитата Сообщение от AlexandrD Посмотреть сообщение
Подскажите, ну например я использую неблокирующие сокеты, как реализовать принятие и отправку данных?
Код
for(set<int>::iterator it = clients.begin(); it != clients.end(); it++)
        {
            if(FD_ISSET(*it, &readset))
            {
                bytes_read = recv(*it, buf, 1024, 0);
                if(bytes_read <= 0)
                {
                    close(*it);
                    clients.erase(*it);
                    continue;
                }
            }
        }
не совсем понимаю как реализовать обмен между клиентами, например данные я тут приму, а как потом отправить ответ? за раз данные могут не отправится по идее, а если отправятся то будет большая задержка. Делал раньше на java но я делал каждого клиента в отдельном потоке, но прочёл что это не хорошо если много клиентов
Да да, интересует как передавать и получать данные в таком режиме. С "форточками" (форк) у меня получалось принимать и получать данные, но вариант с форточками не подходит по уже выше сказанным причинам (сам наступил на грабли и осознал). Но есть ли примерчик как в данном варианте принимать/получать данные
0 / 0 / 0
Регистрация: 19.03.2012
Сообщений: 7
22.03.2012, 08:03 30
есть хорошая книжка, моего бывшего преподавателя, там есть решение этой задачи (прозрачное для понимания)
Решений там несколько , зависит от постановленной задачи программы
вот линк на книжку в pdf (начинать читать с 133 стр)
http://www.stolyarov.info/books/pdf/osintro.pdf
0
1563 / 1041 / 94
Регистрация: 17.04.2009
Сообщений: 2,995
22.03.2012, 08:11 31
Прочитай "UNIX. Разработка сетевых приложений" и не будет вопросов. Уже 4ая страница, а niXman даже еще не предложил asio
0
Эксперт С++
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
22.03.2012, 15:50 32
чтож вы тупов беспокоите? теме два года.

Цитата Сообщение от KuKu Посмотреть сообщение
niXman даже еще не предложил asio
дела-дела...
0
22.03.2012, 15:50
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.03.2012, 15:50
Помогаю со студенческими работами здесь

Реализация клиент-серверного приложение
Доброго времени суток, у меня такой вопрос как создать клиент серверное приложение. Пример:...

Архитектура клиент-серверного приложения
Доброго времени суток. Стоит задача - разработать 4 не больших приложения, из них 3 клиента и 1...

Создание клиент-серверного приложения
Доброго дня. Необходимо написать программу обращения матрицы, она должна быть клиент серверной, то...

Создание клиент серверного приложения
Доброго времени суток, уважаемые гуру программирования. Надеюсь на Ваш опыт и доброту. Собственно...


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru