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

Падает собственный вёб-сервер

22.04.2010, 16:49. Показов 1229. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
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
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
#include<unistd.h>  
#include<sys/types.h>  
#include<sys/stat.h>  
#include<sys/socket.h>  
#include<arpa/inet.h>  
#include<netdb.h>  
#include<signal.h>  
#include<fcntl.h>  
#include <pthread.h>
 
 
#define CONNMAX 1000  
#define BYTES 1024  
#define MAX_PATH 260
 
 
char ROOT[MAX_PATH];  
int listenfd, clients[CONNMAX];  
 
 
 
void start_listen(char *port)  
{  
    struct addrinfo hints, *res, *p;  
 
    // getaddrinfo for host  
    memset (&hints, 0, sizeof(hints));  
    hints.ai_family = AF_INET;  
    hints.ai_socktype = SOCK_STREAM;  
    hints.ai_flags = AI_PASSIVE;  
    if (getaddrinfo( NULL, port, &hints, &res) != 0)  
    {  
        perror ("getaddrinfo() error");  
        exit(1);  
    }  
    // socket and bind  
    for (p = res; p!=NULL; p=p->ai_next)  
    {  
        listenfd = socket (p->ai_family, p->ai_socktype, 0);  
        if (listenfd == -1) continue;  
        if (bind(listenfd, p->ai_addr, p->ai_addrlen) == 0) break;  
    }  
    if (p==NULL)  
    {  
        perror ("socket() or bind()");  
        exit(1);  
    }  
 
    freeaddrinfo(res);  
 
    // listen for incoming connections  
    if ( listen (listenfd, 1000000) != 0 )  
    {  
        perror("listen() error");  
        exit(1);  
    }  
}  
 
int init_server()  
{   
    char c;      
 
    //Default Values PATH = ~/ and PORT=4747  
    char PORT[6];  
    strcpy(PORT,"4747");  
    strcpy(ROOT, getenv("PWD"));  
    strcat(ROOT, "/web");
 
 
    printf("%sWeb panel runned at port %s%s%s\n", "\033[92m", "\033[36m", PORT, "\033[0m");
 
    //  printf("Server started at port no. %s%s%s with root directory as %s%s%s\n","\033[92m",PORT,"\033[0m","\033[92m",ROOT,"\033[0m");  
    // Setting all elements to -1: signifies there is no client connected  
    int i;  
    for (i=0; i<CONNMAX; i++)  
        clients[i]=-1;  
    start_listen(PORT);  
 
}  
 
 
//client connection  
void * respond(void * sock_num)  
{  
    int n = (int) sock_num;
    char mesg[99999], *reqline[3], data_to_send[BYTES], path[99999];  
    int rcvd, fd, bytes_read;  
 
    memset( (void*)mesg, (int)'\0', 99999 );  
 
    rcvd=recv(clients[n], mesg, 99999, 0);  
 
    if (rcvd<0)    // receive error  
        fprintf(stderr,("recv() error\n"));  
    else if (rcvd==0)    // receive socket closed  
        fprintf(stderr,"Client disconnected upexpectedly.\n");  
    else    // message received  
    {  
        //printf("%s", mesg);  
        reqline[0] = strtok (mesg, " \t\n");  
        if ( strncmp(reqline[0], "GET\0", 4)==0 )  
        {  
            reqline[1] = strtok (NULL, " \t");  
            reqline[2] = strtok (NULL, " \t\n");  
            if ( strncmp( reqline[2], "HTTP/1.0", 8)!=0 && strncmp( reqline[2], "HTTP/1.1", 8)!=0 )  
            {  
                write(clients[n], "HTTP/1.0 400 Bad Request\n", 25);  
            }  
            else  
            {  
                if ( strncmp(reqline[1], "/\0", 2)==0 )  
                    reqline[1] = (char*)"/status.html";        //Because if no file is specified, index.html will be opened by default (like it happens in APACHE...  
 
                strcpy(path, ROOT);  
                strcpy(&path[strlen(ROOT)], reqline[1]);  
                //printf("file: %s\n", path);  
 
                static int resp_num = 0;
 
                char buff[100];
                sprintf(buff, "Responsed %d times", ++resp_num);
 
                send(clients[n], "HTTP/1.0 200 OK\n\n", 17, 0);  
                send (clients[n], buff, strlen(buff), 0);  
 
            }  
        }  
    }  
 
    //Closing SOCKET  
    shutdown (clients[n], SHUT_RDWR);         //All further send and recieve operations are DISABLED...  
    close(clients[n]);  
    clients[n]=-1;  
} 
 
 
void * http_server_loop (void *)
{
    init_server();
 
    socklen_t addrlen; 
    int slot=0;  
 
    // ACCEPT connections  
    while (1)  
    {  
        sockaddr_in clientaddr;  
        addrlen = sizeof(clientaddr);  
        clients[slot] = accept (listenfd, (sockaddr *) &clientaddr, &addrlen);  
 
        if (clients[slot]<0)  
            fprintf(stderr, "accept() error num: %d\n", clients[slot]);  
        else  
        {  
/*          if ( fork()==0 )  
            {  
                respond(slot);  
                exit(0);  
            }  */
 
            pthread_t thread;
            pthread_create(&thread, NULL, respond, (void*) slot);
        }  
 
        while (clients[slot]!=-1) slot = (slot+1)%CONNMAX;  
    }  
 
    return 0;  
}
 
 
int start_http_server ()
{
    pthread_t thread;
 
    int err_code;
    if (err_code = pthread_create(&thread, NULL, http_server_loop, NULL))
    {
        fprintf(stderr, "pthread_create fails with: %d\n", err_code);
        return 2;
    }
 
    return(0);
}
 
 
 
//////////////////////////////////////////////////////////////////////////
// For testing
//////////////////////////////////////////////////////////////////////////
 
 
int main () 
{
    start_http_server();
 
    usleep(0x7FFFFFFF);
}
Вот эта штука открывает порт 4747 и ждёт входящих HTTP подключений. При этом, в самом начале каунтер кол-ва ответов по какой-то причине может перескочить почти на 10 значений вверх, а после 120-360 обращений сервер просто падает. Код не полностью мой, взял за исходник найденный в интернете сорс. Переписать на асинхронные (неблокирующие) сокеты пока не вариант. Какие будут предложения? Тестировал на Ubuntu.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.04.2010, 16:49
Ответы с готовыми решениями:

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

Собственный сервер
Доброго времени суток! Ребят хочу спросить совета,вот если я разверну дома собственный сервер на...

Собственный сервер
Загорелся идеей: собрать старенький компьютер, который будет раздавать интернет, впихнуть его в...

Собственный прокси сервер
Всем доброго вечера! Скажите пожалуйста, на чём удобней и лучше написать свой собственный прокси...

4
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.04.2010, 19:36 2
Suspended, подруби к нему strace || ltrace незадолго до падения.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
23.04.2010, 10:30 3
C
1
2
3
void * respond(void * sock_num)  
{  
        int n = (int) sock_num;
выше
C
1
2
3
4
5
6
7
#define CONNMAX 1000  
#define BYTES 1024  
#define MAX_PATH 260
 
 
char ROOT[MAX_PATH];  
int listenfd, clients[CONNMAX];
адрес может и не поместиться в int, так как int может не равняться long int'у
да и не факт, что адрес помещается в long int
если большое целое число не помещается в целую переменную, то результат не определён

C
1
    short int a = 1000000000;
ничто не должно обрезаться, результат может быть любым

Добавлено через 1 минуту
да, там потом обращение идёт к clients[n], когда n получено странным образом
0
0 / 0 / 0
Регистрация: 30.09.2014
Сообщений: 2
23.04.2010, 21:08 4
При скорости обращения 2 раза в секунду, в памяти повисают сотки TIME_WAIT'ов, и через 5-10 минут доступные сокеты просто заканчиваются. После этого при попытке accept'a поток падает. Не могу решить эту проблему...
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
24.04.2010, 00:36 5
Suspended, ну это нормально, что они в time_wait висят. Тут несколько вариантов может быть:
- Попробуй как-нибудь контролировать количество подключений, делай задержки при ответах клиенту.
- изменить время закрытия порта в time_wait через опции ядра.
- Попробовать использовать что-нибудь типа SO_REUSEADDR, SO_REUSEPORT.
Вот неплохая статья по этой теме: http://www.titanicum.kiev.ua/?web=280
0
24.04.2010, 00:36
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.04.2010, 00:36
Помогаю со студенческими работами здесь

Не могу зайти на собственный сервер W2k
Стоит сервак win 2000 sp 4, подключены 5 компов, инет работает, локалка работает, с сервака можно...

Почему на сайтах устанавливают редирект на собственный сервер?
Был у меня WIN MOBILE 6.1 телефон. Со временем его IE морально устарел, перестал поддерживать теги....

Падает Сервер
Добрый день, Domino 7.0 6 лет простоял стабильно с недавнего времени начал падать, падает в разное...

Падает сервер
Приветствую. Недавно появилась такая проблема. Есть 20 игровых серверов, все работают стабильно....


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

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