#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.