sending recv() data to a file
- From: arnuld <sunrise@xxxxxxxxxxxxxxx>
- Date: Fri, 18 Jul 2008 09:35:58 +0500
I am creating a server which recv()s the data from the client and send()s
it to a file. The basic design idea is to have a log-server which writes a
file after receiving log information from the clients.
WANTED:
It should work like syslog in Linux:
1.) It will read data from client and creates a new file say "mylog.log"
2.) It will check if a file of same name "mylog.log" already exists and if
its size if less than say 100 KB.
(a) If the size of file is less than 100KB then server will append the
data to that file.
(b)If the size of the file is equal to 100KB then server will create a
new file with same name "mylog.log" after moving the old file to name
like "mylog.log.0" or "mylog.log.5" etc.
(c) if the size of file is less than 100 KB and writing data to file
makes it larger than 100 KB, then server should create a new file.
3.) if the total number of files increase by 10, then server should delete
the oldest file which will be "mylog.log.10"
PROBLEM:
All I know is how to open/create/append to the file( fopen() ) but how to
give same name to each file with a numeric ending and how to determine the
size of the file before reading/writing is beyond my understanding. I have
written the code till recv(), using poll() for multiplexing to save CPU
usage but at the file thing I am dead :( . any help
/* CLS server to handle client logs */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#define SERVER_IP "127.0.0.1"
#define LOG_NAME "cls.log"
enum { ARRSIZE = 1001, BACKLOG = 10, FILESIZE = 100, LOGNUM_MAX = 10 };
int main( int argc, char** argv )
{
int sockfd, acceptfd;
int MYPORT, CONN_MAX;
struct sockaddr_in servaddr, cliaddr;
int recv_bytes, clilen;
char buff[ARRSIZE];
/* Log file preparaion */
int log_cnt;
log_cnt = 0;
if( argc != 3 )
{
perror("USAGE: ./file NUMBER-OF-CLIENTS PORT");
exit( EXIT_FAILURE );
}
else
{
CONN_MAX = atoi( argv[1] );
MYPORT = atoi( argv[2] );
}
memset( &servaddr, '\0', sizeof(struct sockaddr_in) );
memset( &cliaddr, '\0', sizeof(struct sockaddr_in) );
/* poll() preparation */
struct pollfd clients[CONN_MAX];
int nready, curr_index, max_index;
int i, j; /* variables used for indexing */
/* initialize socket internet structures */
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);
if( inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr) < 0 )
{
perror("INET_PTON() error");
exit( EXIT_FAILURE );
}
if( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
{
perror("SOCKET() error");
exit( EXIT_FAILURE );
}
printf("SOCKET() done\n");
if( bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr)) < 0 )
{
perror("BIND() error");
exit( EXIT_FAILURE );
}
printf("BIND() done\n");
if( listen(sockfd, BACKLOG) < 0 )
{
perror("LISTEN() error");
exit( EXIT_FAILURE );
}
printf("LISTEN() done\n");
/*poll() initalization */
clients[0].fd = sockfd;
clients[0].events = POLLIN;
curr_index = 0;
max_index = 0;
printf("Entering POLL()'s infinite LOOP\n");
for( ; ; )
{
if( (nready = poll(clients, max_index + 1, -1)) <= 0 )
{
perror("POLL() error");
exit(EXIT_FAILURE);
}
printf("POLL() done\n");
if( clients[0].revents & POLLIN )
{
/* check if we are exceeding the maximum connections */
if( curr_index > CONN_MAX )
{
perror("too many connections");
continue;
}
clilen = sizeof( struct sockaddr_in );
if( (acceptfd = accept(sockfd, (struct sockaddr*)&cliaddr, &clilen)) < 0 )
{
perror("ACCEPT() error");
exit( EXIT_FAILURE );
}
printf("ACCEPTED\n");
for( i=1; i < CONN_MAX; ++i )
{
if( clients[i].fd < 0 )
{
clients[i].fd = acceptfd;
/* FD added, so we don't need to do anything else */
break;
}
}
if( curr_index > max_index )
{
max_index = curr_index;
}
if( --nready <= 0 )
{
continue;
}
} /* finished with checking the readable FDs */
/* check the readbale FDs for data */
for( j = 0; j < max_index; ++j )
{
if( clients[j].fd < 0 )
{
continue;
}
if( clients[j].fd & (POLLIN | POLLERR) )
{
if( (recv_bytes = recv(clients[j].fd, buff, ARRSIZE, 0)) <= 0 )
{
perror("CLIENT_SIDE problem");
close( clients[i].fd );
clients[j].fd = -1;
}
else
{
/* save that data to a text-file
1.) check if we are exceeding the number of files:
(a) if we are exceeding, remove the oldest text-file and create a new file.
(b) else go to step 2
2.) check if we are exceeding the size of the file being written to:
(a) if yes, create a new file
(b) else, append the data to the latest file.
*/
}
if( --nready <= 0 )
{
break; /* no more redable FDs, so break out of this reading data loop */
}
}
} /* for loop for reading data */
} /* for( ; ; ) loop */
return 0;
}
--
www.lispmachine.wordpress.com
my email is @ the above blog
check the "About Myself" page
.
- Follow-Ups:
- Re: sending recv() data to a file
- From: Jens Thoms Toerring
- Re: sending recv() data to a file
- Prev by Date: Re: files "." and ".." from readdir()
- Next by Date: Re: sending recv() data to a file
- Previous by thread: 7 Unix Admin needed for contract position in Texas and Georgia - secret or interim clearance rqd
- Next by thread: Re: sending recv() data to a file
- Index(es):
Relevant Pages
|