Форум программистов, компьютерный форум CyberForum.ru

Потоковый сервер на С++ - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Составить две программы, первая из которых вводит составные части структуры данных http://www.cyberforum.ru/cpp-beginners/thread825421.html
Составить две программы, первая из которых вводит составные части структуры данных, приведённой в индивидуальном варианте, как десятичные числа и формирует из них заданную упакованную структуру как 16-ричное число. Вторая программа вводит упакованную структуру как 16-ричное число и выводит значения отдельных её составных частей как десятичные числа. Программы должны быть офорлены как решение с...
C++ Сигнал аналогового входа в С++ Можно ли при помощи сигнала аналогового входа микрофона запустить какое-то действие в консольном c + +. Если возможно, то как это реализовать? Какие библиотеки подключать? http://www.cyberforum.ru/cpp-beginners/thread825417.html
C++ лексический анализ
Добрый вечер всем. У меня такая проблема: мне надо разобрать строку на запчасти. Смысл такой - с клавиатуры вводится многочлен, его надо разобрать на мономы, и сложить их в массив, они нужны мне будут для последующей работы. разобрать вроде получилось, а вот как эти кусочки сложить в массив - пока непонятно. Вот код - подскажите пожалуйста где я опять накосячил. точнее говоря это черновик кода....
C++ Указатели и разадресация
Программа осуществляет поиск файлов и их сортировку. В массив, хранящий атрибуты найденных файлов заносятся адреса атрибутов а не нужная мне инфа(насколько я понял). Помогите плз,третий вечер сижу... #include "stdafx.h" #include "conio.h" #include "stdlib.h" #include "io.h" #include "time.h" #include "cstringt.h" #include "iostream" #include "iomanip" #include <fstream>
C++ Осуществить поиск комбинации с клавиатуры http://www.cyberforum.ru/cpp-beginners/thread825397.html
Осуществить точный поиск заданной с клавиатуры произвольной последовательности символов (строки) в файле Input.txt. Вывести на экран и в файл Output.txt искомую строку, количество совпадений, а также номер строки и столбца (позиции символа в строке), в которых находится первый символ совпадения. Программа должна обеспечивать многократный поиск, т.е. по окончании процесса поиска повторно...
C++ неразрешенный внешний символ В общем, проблема: подключаю библиотеку tbb (параллельные вычисления) и при компиляции выдается ошибка: " Ошибка 4 error LNK2001: неразрешенный внешний символ ""public: class tbb::task & __thiscall tbb::internal::allocate_child_proxy::allocate(unsigned int)const " (?allocate@allocate_child_proxy@internal@tbb@@QBEAAVtask@3@I@Z)" d:\documents and settings\Мама\мои документы\visual studio... подробнее

Показать сообщение отдельно
kiruhin
0 / 0 / 0
Регистрация: 01.04.2013
Сообщений: 6
01.04.2013, 22:43     Потоковый сервер на С++
Добрый день.
Стала задача написать сервер на плюсах (под линукс). Признаться, данный язык только начал осваивать, поэтому могу показаться совсем уж нубом (за что прошу больно не пинать ). Итак, задача:
1. Реализация потокового (pre-thread) сервера на С++ под Linux (GNU)
2. В данном случае не оговариваются действия сервера (его логика - это сам осилю), а только грамотное построение модели (принял - передал)
3. Подчеркиваю - код для Linux
Начал с того, что гуглил много. В итоге нашел некий "пример" (код ниже), который взял за основу, которую в последствии буду "допиливать". Итак, код был взят отсюда:
http://www.unix.com/programming/1761...ads-sleep.html
Дублирую код в топик:
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
#include <pthread.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
 
#define MAX_CLIENT_PER_THREAD 300
#define MAX_THREAD 200
#define PORT 3355
#define MAX_CLIENT_BUFFER 256
/*#define DEBUG*/
 
int listenfd;
 
typedef struct {
    pthread_t tid;
    int client_count;
    int clients[MAX_CLIENT_PER_THREAD];
} Thread;
 
pthread_cond_t new_connection_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t new_connection_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 
Thread threads[MAX_THREAD];
 
void nonblock(int sockfd)
{
    int opts;
    opts = fcntl(sockfd, F_GETFL);
    if(opts < 0)
    {
        perror("fcntl(F_GETFL)\n");
        exit(1);
    }
    opts = (opts | O_NONBLOCK);
    if(fcntl(sockfd, F_SETFL, opts) < 0) 
    {
        perror("fcntl(F_SETFL)\n");
        exit(1);
    }
}
 
void *thread_init_func(void *arg)
{
    int tid = (int) arg;
    
    int readsocks;
    int i;
    char buffer[MAX_CLIENT_BUFFER];
    char c;
    int n;
#ifdef DEBUG
    printf("thread %d created\n", tid);
    printf("sizeof thread.clients: %d\n", sizeof(threads[tid].clients));
#endif
    memset((int *) &threads[tid].clients, 0, sizeof(threads[tid].clients));
    memset((char *) &buffer, 0, sizeof(buffer));    
    while(1)
    {
#ifdef DEBUG
        printf("thread %d running, client count: %d\n", tid, threads[tid].client_count);
        sleep(3);
#endif
        sleep(1); /* <-- it works ??? :-| */
 
        for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
        {
            if(threads[tid].clients[i] != 0)
            {
                n = recv(threads[tid].clients[i], buffer, MAX_CLIENT_BUFFER, 0);
                if(n == 0)
                {
#ifdef DEBUG
                    printf("client %d closed connection 0\n", threads[tid].clients[i]);
#endif
                    threads[tid].clients[i] = 0;
                    threads[tid].client_count--;
                    memset((char *) &buffer, 0, strlen(buffer));
                }
                else if(n < 0)
                {
                    if(errno == EAGAIN)
                    {
#ifdef DEBUG
                        printf("errno: EAGAIN\n");
#endif
                    }
                    else {
#ifdef DEBUG
                        printf("errno: %d\n", errno);
#endif
                        threads[tid].clients[i] = 0;
                        threads[tid].client_count--;
                        memset( (char *) &buffer, 0, strlen(buffer));
#ifdef DEBUG
                        printf("client %d closed connection -1\n", threads[tid].clients[i]);
#endif
                    }
                }
                else {
#ifdef DEBUG
                    printf("%d bytes received from %d - %s\n", n, threads[tid].clients[i], buffer);
#endif
                    
                    send(threads[tid].clients[i], buffer, strlen(buffer), 0);
                    memset((char *) &buffer, 0, strlen(buffer));
                }
            }
        }
    }
}
 
int choose_thread()
{
    int i=MAX_THREAD-1;
    int min = 0;
    while(i > -1)
    {
        if(threads[i].client_count < threads[i-1].client_count)
        {
            min = i;
            break;
        }
        i--;
    }       
    return min;
}
 
int main()
{
    char c;
    struct sockaddr_in srv, cli;
    int clifd;
    int tid;
    int i;
    int choosen;
 
    signal(SIGPIPE, SIG_IGN);
    
    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("sockfd\n");
        exit(1);
    }
    bzero(&srv, sizeof(srv));
    srv.sin_family = AF_INET;
    srv.sin_addr.s_addr = INADDR_ANY;
    srv.sin_port = htons(PORT);
 
    if( bind(listenfd, (struct sockaddr *) &srv, sizeof(srv)) < 0)
    {
        perror("bind\n");
        exit(1);
    }
    
    listen(listenfd, 1024);
 
    
    /* create threads  */
    for(i = 0; i < MAX_THREAD; i++)
    {
        pthread_create(&threads[i].tid, NULL, &thread_init_func, (void *) i);
        threads[i].client_count = 0;
    }
    
 
    for( ; ; )
    {
        clifd = accept(listenfd, NULL, NULL);
        nonblock(clifd);
 
        pthread_mutex_lock(&new_connection_mutex);
        
        choosen = choose_thread();
 
        for(i = 0; i < MAX_CLIENT_PER_THREAD; i++)
        {
            if(threads[choosen].clients[i] == 0)
            {
#ifdef DEBUG
                printf("before threads clifd\n");
#endif
                threads[choosen].clients[i] = clifd;
#ifdef DEBUG
                printf("after threads clifd\n");
#endif
                threads[choosen].client_count++;
                break;
            }
        }
 
#ifdef DEBUG
        printf("choosen: %d\n", choosen);
 
        for(i = 0; i < MAX_THREAD; i++)
        {
            printf("threads[%d].client_count:%d\n", i, threads[i].client_count);
        }
#endif
 
        pthread_mutex_unlock(&new_connection_mutex);
    }
 
    if(errno)
    {
        printf("errno: %d", errno);
    }
    
    return 0;
}
Сам автор этого кода, в своем посте пишет:
"I am trying to writa a multi-client & multi-threaded TCP server.
There is a thread pool. Each thread in the pool will handle
requests of multiple clients.

But here I have a problem. I find a solution but it is not how
it must be... i think. When threads working without sleep(1)
I can't get response from server but when I put sleep(1) in
thread function as you will see in code, everything works fine
and server can make echo nearly for 40000 clients between
1 or 2 seconds. What am I doing wrong here?
"
И это действительно так. С одной оговоркой, что если заккоментировать sleep(1), то это сервер работает именно так, как нужно, НО вводит систему в ступор (загрузка ЦП 100%, что очевидно, т.к. while(1) ) С другой стороны, из-за этого sleep(1), во-первых, ответ сервера возвращается только через секунду, во-вторых, если передать серверу несколько пакетов (передать быстро), то он "склеит" это пакеты в один, как следствие, пакеты невозможно будет разобрать.
Пожалуйста, подскажите:
1. Если приведенный пример (код, взятый за основу) корректный - как можно избежать sleep (1)?
2. Если код в своей основе неверный (или морально устарел, т.к. пост датируется аж 2005 годом) - помогите собрать этот покотовый сервер (хоть пример реально работающего)
3. Обязательно ли объявлять сокет неблокируемым (как в приведенном примере)?
Спасибо огромное!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 13:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru