nick
04-10-2003, 02:54 PM
Hi board,
following part of my code from a chatserver do some strange things.
The Server is runnig about 2 hours without problems (with 1 - 200 Users), but sometimes the server stopps accepting connections, recv and sending messages. The process ist still runnig, after +-15min and reconnect of all users the server works like before.
Do someone have an idea or a hint?
Thanks in advance and sorry for my english.
UPDATED : 16-04-2003
int main(void)
{
struct sockaddr_in myaddr; // server address
struct sockaddr_in remoteaddr; // client address
int listener; // listening socket descriptor
int newfd = 0; // newly accept()ed socket descriptor
int nbytes;
int ssoval=1; // for setsockopt() SO_REUSEADDR, below
int i;
fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
socklen_t addrlen;
signal(SIGPIPE, SIG_IGN); // 0.0.6 - Ignoriert Broken Pipe Ausstieg
signal(SIGCLD, SIG_IGN);
LoadCfg("server.cfg");
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
// get the listener
if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* Set socket to non-blocking */
int flags;
if ((flags = fcntl(listener, F_GETFL, 0)) < 0) {
close(listener);
printf("error getting flags on socket; %i\n", listener);
}
if ((fcntl(listener, F_SETFL, flags | O_NONBLOCK, 0)) < 0) {
close(listener);
printf("error setting socket to non-blocking; %i\n", listener);
}
// bind Port
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(CK_port);
memset(&(myaddr.sin_zero), '\0', 8);
// 0.1.1
ssoval = 1;
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&ssoval, sizeof(ssoval))<0) {
perror("setsockopt");
exit(1);
}
ssoval = 0;
if (setsockopt(listener, SOL_SOCKET, SO_KEEPALIVE, (char *)&ssoval, sizeof(ssoval))<0) {
perror("setsockopt");
exit(1);
}
// 0.1.1
if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
perror("bind");
exit(1);
}
// listen
if (listen(listener, 5) == -1) {
perror("listen");
exit(1);
}
// add the listener to the master set
FD_SET(listener, &master);
// keep track of the biggest file descriptor
fdmax = listener; // so far, it's this one
// Server Startup Screen
init ();
// main loop
for(;;) {
int bufsize = 1023; /* 1K buffer */
char buf[1024] = " ";
read_fds = master; // copy it
if (select(fdmax+1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *) 0) == -1) {
perror("select");
exit(1);
}
// run through the existing connections looking for data to read
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) { // we got one!!
if (i == listener) {
// handle new connections
addrlen = sizeof(remoteaddr);
if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
perror("accept");
} else {
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax) { // erhoeht maximum fd
fdmax = newfd;
}
printf("\n******* [NEW CLIENT FROM %s ON FD %d]\n", inet_ntoa(remoteaddr.sin_addr), newfd);
}
} else {
// handle data from a client
if ((nbytes = recv(i, buf, bufsize, 0)) <= 0) {
if (nbytes == 0) {
printf("SELEC : socket %d hung up\n", i);
} else {
perror("recv");
}
remove_Client(i);
close(i); // close socket - bye bye!
FD_CLR(i, &master); // remove from master set
} else {
buf[nbytes] = '\0'; // null terminate string
printf("RECV< : fd(%i), strlen_buf(%i), bufsize(%i), nbytes(%i)\n", newfd, strlen(buf), bufsize, nbytes);
char *sessid = Regex("^GET /(.*) HTTP", buf);
if (sessid != " ") {
char login[256] = "";
char heute[1024] = "";
struct tm * tm1;
time_t caltime;
caltime = time(NULL);
tm1 = localtime(&caltime);
strftime(heute, 1024, "%H:%M", tm1);
Update_userdata(i, sessid);
Send_Header(i);
sprintf(login, "1140900009CHATMSG|%s||%s|<i>*** %s <b>%s</b> hat den Chat betreten</i><br>",
user[i].sessid, user[i].room, heute, user[i].nick);
printf("%s\n", login); // DEBUG
handleMessage(i, login);
}
if ((Regex("^1140900009CHATMSG(.*)", buf)) != " ") {
handleMessage(i, buf);
}
if ((Regex("^1140900009ADDIGNORE(.*)", buf)) != " ") {
Add_Ignore(i, buf);
}
} // recv end
}
}
} // fd run
} // loop end
return 0;
} // main end
following part of my code from a chatserver do some strange things.
The Server is runnig about 2 hours without problems (with 1 - 200 Users), but sometimes the server stopps accepting connections, recv and sending messages. The process ist still runnig, after +-15min and reconnect of all users the server works like before.
Do someone have an idea or a hint?
Thanks in advance and sorry for my english.
UPDATED : 16-04-2003
int main(void)
{
struct sockaddr_in myaddr; // server address
struct sockaddr_in remoteaddr; // client address
int listener; // listening socket descriptor
int newfd = 0; // newly accept()ed socket descriptor
int nbytes;
int ssoval=1; // for setsockopt() SO_REUSEADDR, below
int i;
fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
socklen_t addrlen;
signal(SIGPIPE, SIG_IGN); // 0.0.6 - Ignoriert Broken Pipe Ausstieg
signal(SIGCLD, SIG_IGN);
LoadCfg("server.cfg");
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
// get the listener
if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* Set socket to non-blocking */
int flags;
if ((flags = fcntl(listener, F_GETFL, 0)) < 0) {
close(listener);
printf("error getting flags on socket; %i\n", listener);
}
if ((fcntl(listener, F_SETFL, flags | O_NONBLOCK, 0)) < 0) {
close(listener);
printf("error setting socket to non-blocking; %i\n", listener);
}
// bind Port
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(CK_port);
memset(&(myaddr.sin_zero), '\0', 8);
// 0.1.1
ssoval = 1;
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&ssoval, sizeof(ssoval))<0) {
perror("setsockopt");
exit(1);
}
ssoval = 0;
if (setsockopt(listener, SOL_SOCKET, SO_KEEPALIVE, (char *)&ssoval, sizeof(ssoval))<0) {
perror("setsockopt");
exit(1);
}
// 0.1.1
if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
perror("bind");
exit(1);
}
// listen
if (listen(listener, 5) == -1) {
perror("listen");
exit(1);
}
// add the listener to the master set
FD_SET(listener, &master);
// keep track of the biggest file descriptor
fdmax = listener; // so far, it's this one
// Server Startup Screen
init ();
// main loop
for(;;) {
int bufsize = 1023; /* 1K buffer */
char buf[1024] = " ";
read_fds = master; // copy it
if (select(fdmax+1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *) 0) == -1) {
perror("select");
exit(1);
}
// run through the existing connections looking for data to read
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) { // we got one!!
if (i == listener) {
// handle new connections
addrlen = sizeof(remoteaddr);
if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
perror("accept");
} else {
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax) { // erhoeht maximum fd
fdmax = newfd;
}
printf("\n******* [NEW CLIENT FROM %s ON FD %d]\n", inet_ntoa(remoteaddr.sin_addr), newfd);
}
} else {
// handle data from a client
if ((nbytes = recv(i, buf, bufsize, 0)) <= 0) {
if (nbytes == 0) {
printf("SELEC : socket %d hung up\n", i);
} else {
perror("recv");
}
remove_Client(i);
close(i); // close socket - bye bye!
FD_CLR(i, &master); // remove from master set
} else {
buf[nbytes] = '\0'; // null terminate string
printf("RECV< : fd(%i), strlen_buf(%i), bufsize(%i), nbytes(%i)\n", newfd, strlen(buf), bufsize, nbytes);
char *sessid = Regex("^GET /(.*) HTTP", buf);
if (sessid != " ") {
char login[256] = "";
char heute[1024] = "";
struct tm * tm1;
time_t caltime;
caltime = time(NULL);
tm1 = localtime(&caltime);
strftime(heute, 1024, "%H:%M", tm1);
Update_userdata(i, sessid);
Send_Header(i);
sprintf(login, "1140900009CHATMSG|%s||%s|<i>*** %s <b>%s</b> hat den Chat betreten</i><br>",
user[i].sessid, user[i].room, heute, user[i].nick);
printf("%s\n", login); // DEBUG
handleMessage(i, login);
}
if ((Regex("^1140900009CHATMSG(.*)", buf)) != " ") {
handleMessage(i, buf);
}
if ((Regex("^1140900009ADDIGNORE(.*)", buf)) != " ") {
Add_Ignore(i, buf);
}
} // recv end
}
}
} // fd run
} // loop end
return 0;
} // main end