Добрый день, не могу понять в чём проблема, написал процесс на СИ под UNIX, всё стабильно и правильно работает, контролирую по логфайлу(каждые 30 секунд в файл пишется информация)
Но почему-то есть замирания на 1 час иногда на 30 мин, потом работа снова продолжается. И так постоянно. Посоветуйте, что может быть. Программа по средством сокета опрашивает сервер, каждые 30 секунд.Модель организована следующим образом:
1)Форкаю процесс
2)В основном цикле вызываю функцию start()
3)функция start()в дополнительном цикле соединяется с сервером, получает данные, разрывает соединение и выходит из дополнительного цикла
4)Программа переходит в основной цикл, засыпает на 30 сек и снова вызывает функцию start()...Привожу код программы:
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>#include <errno.h>
#include <string.h>#define RUNNING_DIR "/var/temp/my/@"
#define LOCK_FILE "log_d.pid"
#define LOG_FILE "log_d.log"
#define DBG_FILE "log_d.dbg"#define MAXSTRLEN 512
#define MAXRCVLEN 500
#define PORTNUM 8566extern int errno;
/* Объявляем фукции */
void start(void);
void debug_begin(void);
void daemonize(void);
void debug_mess(char *filename, char *from, char *message);
void log_message(char *filename, char *message);
void write_s(int mysocket, char *data);
char *util_base64_encode(char *txt);
/*************************************/main(){
daemonize();
log_message(LOG_FILE, "Daemon is started");
while(1){
/* Печатаем шапку дебага */
debug_begin();
/* Подключаемся HSD серверу */
start();
//log_message(LOG_FILE, "Проверка работы !!!");
/* Выводим чо-нибудь для контроля */
log_message(LOG_FILE, strerror(errno));
/* Делаем паузу X секунд */
sleep(30);
}
}/* Функция соединения с HSD сервером */
void start(void){
int flag = 0;
int len, mysocket, result;
struct sockaddr_in dest;
char buffer[MAXRCVLEN + 1];/* Создаем сокет */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("10.65.10.20"); /* set destination IP number */
dest.sin_port = htons(PORTNUM); /* set destination port number */
/* Пытаемся установить соединение с сервером */
if ((connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr))) < 0) {
/* Запускаем HSD Server */
system ("/var/server/bin/run_hsd.sh & 2>&1");
/* Ждём запуска HSD Servera */
sleep(5);
/* Соединяемся с сервером */
connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));
}
/* else */
while(1){/* Читаем данные от сервера */
result = recv(mysocket, buffer, MAXRCVLEN, 0);
/* Исключаем символ окончания строки */
buffer[result] = '\0';
if(strcmp(buffer, "ACKN\n")==0 && flag == 0)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "HELO\r\n");
} else if(strcmp(buffer, "ACKN\n")==0 && flag == 1)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "EXEC\r\n");
flag = 2;
} else if(strcmp(buffer, "ACKN\n")==0 && flag == 2)
{
debug_mess(DBG_FILE, " <--- ", buffer);
flag = 3;
} else if(strncmp(buffer, "ACKN HSD Server", 15)==0)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "INIT ALARM_SUMMARY\r\n");
flag = 1;
} else if(strcmp(buffer, "RSLT ALARM_SUMMARY\n")==0 || strcmp(buffer, "PARA SNAPSHOT\n")==0 || strncmp(buffer, "VALU", 4)==0 || strncmp(buffer, "VALR", 4)==0 || strcmp(buffer, "ETBL\n")==0)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "ACKN\r\n");
} else if(strncmp(buffer, "TABL SUMMARY 6 ", 15)==0)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Определяем количество строк в таблице ошибок */
char *stroka = (char*) malloc (MAXSTRLEN + 1);
int bytes = snprintf(stroka, MAXSTRLEN, "ACKN 1 %s\r\n", &buffer[15]);
if (bytes > MAXSTRLEN) {
/* Освобождаем память */
free(stroka);
log_message(LOG_FILE, "Error -->>> No free memory!");
return;
}
write_s(mysocket, stroka);
} else if(strcmp(buffer, "QUIT\n")==0)
{
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "ACKN\r\n");
/* Закрываем сокет */
close(mysocket);
/* Выходим из цикла */
break;
} else
{
log_message(LOG_FILE, strerror(errno));
debug_mess(DBG_FILE, " <<->>", buffer);
/* Закрываем сокет */
close(mysocket);
/* Выходим из цикла */
break;
}
//log_message(LOG_FILE, buffer);
//sleep(1);
}}
/* Функция записи в сокет */
void write_s(int mysocket, char *data){
write(mysocket, data, strlen(data));
debug_mess(DBG_FILE, " ---> ", data);
}/* Функция шапки дебага */
void debug_begin(void){
struct timeval timenow;
FILE *debugfile;
/* функция времени */
gettimeofday(&timenow, NULL);
debugfile = fopen(DBG_FILE, "a");
if(!debugfile) return;
fprintf(debugfile,"%s", "########################## ");
fprintf(debugfile,"%s", ctime(&timenow.tv_sec));
fprintf(debugfile,"%s\r\n", " ##########################");
fclose(debugfile);
}/* Функция дебага демона */
void debug_mess(char *filename, char *from, char *message){
FILE *debugfile;
debugfile = fopen(filename, "a");
if(!debugfile) return;
fprintf(debugfile,"%s %s\r\n", from, message);
fclose(debugfile);
}/* Функция логирования сообщений демона */
void log_message(char *filename, char *message){
struct timeval timenow;
FILE *logfile;
/* функция времени */
gettimeofday(&timenow, NULL);
logfile=fopen(filename,"a");
if(!logfile) return;
fprintf(logfile,"%s %s\r\n", message, ctime(&timenow.tv_sec));
fclose(logfile);
}/* Функция обработки сигналов */
void signal_handler(int sig){
switch(sig) {
case SIGHUP:
log_message(LOG_FILE,"hangup signal catched");
break;
case SIGTERM:
log_message(LOG_FILE,"Daemon is killed :");
exit(0);
break;
}
}/* Функция демона */
void daemonize(){
int i,lfp;
char str[10];
if(getppid()==1) return; /* already a daemon */
i=fork();
if (i<0) exit(1); /* fork error */
if (i>0) exit(0); /* parent exits */
/* child (daemon) continues */
setsid(); /* obtain a new process group */
for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standart I/O */
umask(027); /* set newly created file permissions */
chdir(RUNNING_DIR); /* change running directory */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) exit(1); /* can not open */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* can not lock */
/* first instance continues */
sprintf(str,"%d\n",getpid());
write(lfp,str,strlen(str)); /* record pid to lockfile */
signal(SIGCHLD,SIG_IGN); /* ignore child */
signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGHUP,signal_handler); /* catch hangup signal */
signal(SIGTERM,signal_handler); /* catch kill signal */
}
Помогите разобраться, где закралась ошибка, что я делаю не правильно...?Думал может организовать модель так, чтоб соединение с сервером висело постоянно, но как проверять перед опросом, не отвалилось ли соединение или не разорвал ли его сервер???
На солярке чтоли? Или на говно-линуксе?
>На солярке чтоли? Или на говно-линуксе?Да нет, Open Unixware 7...
>[оверквотинг удален]
>3)функция start()в дополнительном цикле соединяется с сервером, получает данные, разрывает соединение и
>выходит из дополнительного цикла
>4)Программа переходит в основной цикл, засыпает на 30 сек и снова вызывает
>функцию start()...
>
>Помогите разобраться, где закралась ошибка, что я делаю не правильно...?
>
>Думал может организовать модель так, чтоб соединение с сервером висело постоянно, но
>как проверять перед опросом, не отвалилось ли соединение или не разорвал
>ли его сервер???поглядев на код ничего подозрительного не вижу.
вопрос, а в каком месте замирает программа?
у вас тут два лог файла ведеться! это не очень хорошо! хотябы на время направьте вывод в один файл, тогда можно будет проследить хронологию всех событий и выводов
попробуйте
а) добавить debug_end() после вызова start()
б) не закрывайте файлы отладки, пусть будут открытыми.
в) если всетаки торомзиться на sleep, можно попробовать реализовать задержку через alarm
г) получите возврат от фукнции sleep, и запишите его в лог.
>[оверквотинг удален]
>вопрос, а в каком месте замирает программа?
>у вас тут два лог файла ведеться! это не очень хорошо! хотябы
>на время направьте вывод в один файл, тогда можно будет проследить
>хронологию всех событий и выводов
>попробуйте
>а) добавить debug_end() после вызова start()
>б) не закрывайте файлы отладки, пусть будут открытыми.
>в) если всетаки торомзиться на sleep, можно попробовать реализовать задержку через alarm
>
>г) получите возврат от фукнции sleep, и запишите его в лог.Спасибо, попробую :))
А, что это значит debug_end() ?
О результате отпишусь!
1. дождаться када зависнет на часок и просто дебагером подключиться к процессу, посмотреть в каком он состоянии, может сразу ошибку увидишь (ессно включить отладочную инфу при компиляции и отключить оптимизацию).
2. сколько времени висит первый connect() если сервер не поднят?
3. Почему 5 сек ждешь старта сервера, и почему не анализируешь запустился или нет по какому-нить флагу от сервера? Сколько времени он реально стартует?
4. сколько времени висит второй connect() ?
5. почему нет проверок кода возврата для socket(), connect(), recv(), write()?
>1. дождаться када зависнет на часок и просто дебагером подключиться к процессу,
>посмотреть в каком он состоянии, может сразу ошибку увидишь (ессно включить
>отладочную инфу при компиляции и отключить оптимизацию).
>2. сколько времени висит первый connect() если сервер не поднят?
>3. Почему 5 сек ждешь старта сервера, и почему не анализируешь запустился
>или нет по какому-нить флагу от сервера? Сколько времени он реально
>стартует?
>4. сколько времени висит второй connect() ?
>5. почему нет проверок кода возврата для socket(), connect(), recv(), write()?Ой, как много полезного Спасибо! Но можно немного подробнее, я честно говоря первый раз пишу на Си да ещё и под Unix... Но очень хочу написать)))
1)Как дебагером подключиться к процессу? мне как раз что-то такого не хватает...
2)Как узнать запустился или нет сервер, я не знаю, просто если конект есть-значит поднят..
>[оверквотинг удален]
>>или нет по какому-нить флагу от сервера? Сколько времени он реально
>>стартует?
>>4. сколько времени висит второй connect() ?
>>5. почему нет проверок кода возврата для socket(), connect(), recv(), write()?
>
>Ой, как много полезного Спасибо! Но можно немного подробнее, я честно говоря
>первый раз пишу на Си да ещё и под Unix... Но
>очень хочу написать)))
>
>1)Как дебагером подключиться к процессу? мне как раз что-то такого не хватает...смотрите ключики командной строки дебагера, должен быть ключик указывающий pid процесса, если там есть gdb, то --pid=XXXX
>
>2)Как узнать запустился или нет сервер, я не знаю, просто если конект
>есть-значит поднят..Зависит от самого сервера
Попробовал просто добавить строгости в исходник, но толком проверить логику сейчас времени нету. Можешь diff'ом посмотреть изменения и протестировать работу, вдруг помогло:#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>#include <errno.h>
#include <string.h>#define RUNNING_DIR "/var/temp/my/@"
#define LOCK_FILE "log_d.pid"
#define LOG_FILE "log_d.log"
#define DBG_FILE "log_d.dbg"#define MAXSTRLEN 512
#define MAXRCVLEN 500
#define PORTNUM 8566extern int errno;
/* Объявляем фукции */
void start(void);
void debug_begin(void);
void daemonize(void);
void debug_mess(const char *filename, const char *from, const char *message);
void log_message(const char *filename, const char *message);
void write_s(int mysocket, const char *data);
/*************************************/int main(void)
{
daemonize();
log_message(LOG_FILE, "Daemon is started");while (1) {
/* Печатаем шапку дебага */
debug_begin();
/* Подключаемся HSD серверу */
start();//log_message(LOG_FILE, "Проверка работы !!!");
/* Выводим чо-нибудь для контроля */
log_message(LOG_FILE, strerror(errno));
/* Делаем паузу X секунд */
sleep(30);
}return 0;
}/* Функция соединения с HSD сервером */
void start(void)
{
int flag = 0;
int mysocket, result;
struct sockaddr_in dest;
char buffer[MAXRCVLEN + 1];/* Создаем сокет */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
if (mysocket == -1) return;memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("10.65.10.20"); /* set destination IP number */
dest.sin_port = htons(PORTNUM); /* set destination port number *//* Пытаемся установить соединение с сервером */
if ((connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr))) < 0) {
/* Запускаем HSD Server */
system ("/var/server/bin/run_hsd.sh & 2>&1");
/* Ждём запуска HSD Servera */
sleep(5);
/* Соединяемся с сервером */
if (connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr)) == -1) return;
}
/* else */
while(1){/* Читаем данные от сервера */
memset(buffer, 0, MAXRCVLEN + 1);
result = recv(mysocket, buffer, MAXRCVLEN, 0);
if (result == -1) return;/* Исключаем символ окончания строки */
buffer[result] = '\0';if (strcmp(buffer, "ACKN\n") == 0 && flag == 0) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "HELO\r\n");
}
else if (strcmp(buffer, "ACKN\n") == 0 && flag == 1) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "EXEC\r\n");
flag = 2;
}
else if (strcmp(buffer, "ACKN\n") == 0 && flag == 2) {
debug_mess(DBG_FILE, " <--- ", buffer);
flag = 3;
}
else if (strncmp(buffer, "ACKN HSD Server", 15) == 0) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "INIT ALARM_SUMMARY\r\n");
flag = 1;
}
else if (strcmp(buffer, "RSLT ALARM_SUMMARY\n") == 0 ||
strcmp(buffer, "PARA SNAPSHOT\n") == 0 ||
strncmp(buffer, "VALU", 4) == 0 ||
strncmp(buffer, "VALR", 4) == 0 ||
strcmp(buffer, "ETBL\n") == 0) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "ACKN\r\n");
}
else if (strncmp(buffer, "TABL SUMMARY 6 ", 15) == 0) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Определяем количество строк в таблице ошибок */
char *stroka = NULL;
int bytes;stroka = (char *)malloc(MAXSTRLEN + 1);
if (stroka == NULL) return;
memset(stroka, 0, MAXSTRLEN + 1);bytes = snprintf(stroka, MAXSTRLEN, "ACKN 1 %s\r\n", &buffer[15]);
if (bytes > MAXSTRLEN) {
/* Освобождаем память */
free(stroka);
log_message(LOG_FILE, "Error -->>> No free memory!");
return;
}
write_s(mysocket, stroka);
free(stroka);
}
else if (strcmp(buffer, "QUIT\n") == 0) {
debug_mess(DBG_FILE, " <--- ", buffer);
/* Отправляем сообщение серверу */
write_s(mysocket, "ACKN\r\n");
/* Закрываем сокет */
close(mysocket);
/* Выходим из цикла */
break;
}
else {
log_message(LOG_FILE, strerror(errno));
debug_mess(DBG_FILE, " <<->>", buffer);
/* Закрываем сокет */
close(mysocket);
/* Выходим из цикла */
break;
}
}
}/* Функция записи в сокет */
void write_s(int mysocket, const char *data)
{
write(mysocket, data, strlen(data));
debug_mess(DBG_FILE, " ---> ", data);
}/* Функция шапки дебага */
void debug_begin(void)
{
struct timeval timenow;
FILE *debugfile = NULL;/* функция времени */
gettimeofday(&timenow, NULL);debugfile = fopen(DBG_FILE, "a");
if (!debugfile) return;fprintf(debugfile, "%s", "########################## ");
fprintf(debugfile, "%s", ctime(&timenow.tv_sec));
fprintf(debugfile, "%s\r\n", " ##########################");fclose(debugfile);
}/* Функция дебага демона */
void debug_mess(const char *filename, const char *from, const char *message)
{
FILE *debugfile = NULL;debugfile = fopen(filename, "a");
if(!debugfile) return;fprintf(debugfile, "%s %s\r\n", from, message);
fclose(debugfile);
}/* Функция логирования сообщений демона */
void log_message(const char *filename, const char *message)
{
struct timeval timenow;
FILE *logfile = NULL;/* функция времени */
gettimeofday(&timenow, NULL);logfile = fopen(filename,"a");
if (!logfile) return;fprintf(logfile,"%s %s\r\n", message, ctime(&timenow.tv_sec));
fclose(logfile);
}/* Функция обработки сигналов */
void signal_handler(int sig){
switch(sig) {
case SIGHUP:
log_message(LOG_FILE,"hangup signal catched");
break;
case SIGTERM:
log_message(LOG_FILE,"Daemon is killed :");
exit(0);
break;
}
}/* Функция демона */
void daemonize(void)
{
int i, lfp;
char str[10];if (getppid() == 1) return; /* already a daemon */
i = fork();
if (i < 0) exit(1); /* fork error */
if (i > 0) exit(0); /* parent exits *//* child (daemon) continues */
setsid(); /* obtain a new process group */for (i = getdtablesize(); i >= 0; --i)
close(i); /* close all descriptors */i = open("/dev/null", O_RDWR);
if (i < 0) exit(1);dup(i);
dup(i); /* handle standart I/O */
umask(027); /* set newly created file permissions */
chdir(RUNNING_DIR); /* change running directory */lfp = open(LOCK_FILE, O_RDWR | O_CREAT, 0640);
if (lfp < 0) exit(1); /* can not open */if (lockf(lfp, F_TLOCK, 0) < 0) exit(0); /* can not lock */
/* first instance continues */
memset(str, 0, 10);
sprintf(str, "%d\n", getpid());
write(lfp, str, strlen(str)); /* record pid to lockfile */signal(SIGCHLD, SIG_IGN); /* ignore child */
signal(SIGTSTP, SIG_IGN); /* ignore tty signals */
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGHUP, signal_handler); /* catch hangup signal */
signal(SIGTERM, signal_handler); /* catch kill signal */
}
>Попробовал просто добавить строгости в исходник, но толком проверить логику сейчас времени
>нету. Можешь diff'ом посмотреть изменения и протестировать работу, вдруг помогло:
>Спасибо, тестирую))
Почему-то в лог пишет "Bad file number":
Daemon is started Mon Mar 2 16:36:46 2009
Bad file number Mon Mar 2 16:36:49 2009
Bad file number Mon Mar 2 16:37:21 2009
Bad file number Mon Mar 2 16:37:53 2009
Судя по строкам 49 и 154 - log_message(LOG_FILE, strerror(errno)); - это последний код ошибки, содержащийся в переменной errno и по которому формируется сообщение. Детально от какой именно операции он возникает надо смотреть на месте.Еще пара ошибок (сорри, сразу не заметил):
1. 2 раза подряд функцию connect() для сокетов TCP вызывать нельзя:
"Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association." (с) man 2 connect
2. В функции start() есть return без предварительного close() для mysocket: строки 81, 89, 131, 139.
>Судя по строкам 49 и 154 - log_message(LOG_FILE, strerror(errno)); - это последний
>код ошибки, содержащийся в переменной errno и по которому формируется сообщение.
>Детально от какой именно операции он возникает надо смотреть на месте.
>
>
>Еще пара ошибок (сорри, сразу не заметил):
>1. 2 раза подряд функцию connect() для сокетов TCP вызывать нельзя:
>"Generally, connection-based protocol sockets may successfully connect() only once;
>connectionless protocol sockets may use connect() multiple times to change their
>association." (с) man 2 connectЭто значит что удачно войти в соединение можно только один раз для connecttion-based протокола (TCP). А в данном случае второй раз функция вызывается в случае неудачи, так что тут норм.
>2. В функции start() есть return без предварительного close() для mysocket: строки
>81, 89, 131, 139.Вот это путь к переполнению таблицы открытых дескрипторов.
>Детально от какой именно операции он возникает надо смотреть на месте.
>Как же мне это всетаки выяснить...?
>Еще пара ошибок (сорри, сразу не заметил):
>1. 2 раза подряд функцию connect() для сокетов TCP вызывать нельзя:
>"Generally, connection-based protocol sockets may successfully connect() only once;
>connectionless protocol sockets may use connect() multiple times to change their
>association." (с) man 2 connect
>Так там первый проверяется, если нет конекта, то запускается сервер и повторяем попытку соединения...Я так понимаю, если соединение небыло установлено то и закрывать сокет нет смысла???
>
>2. В функции start() есть return без предварительного close() для mysocket: строки
>81, 89, 131, 139.
>
>Вот это путь к переполнению таблицы открытых дескрипторов.Это я не понял, как будет правильно сделать????
Програма уже полтора дня работает нормально, не считая
Bad file number Mon Mar 2 16:36:49 2009
Bad file number Mon Mar 2 16:37:21 2009
Bad file number Mon Mar 2 16:37:53 2009
....
....
Bad file number Mon Mar 3 10:35:53 2009Ещё вопрос, мне рекомендуют использовать неблокированный режим сокета, на сколько это оправдано и нет ли понятного примера реализации...?
ВСЕМ Спасибо за помощь!
>>Вот это путь к переполнению таблицы открытых дескрипторов.
>Это я не понял, как будет правильно сделать????закрывать перед return сокет там где он больше уже не нужен.
>[оверквотинг удален]
>Bad file number Mon Mar
> 2 16:36:49 2009
>Bad file number Mon Mar
> 2 16:37:21 2009
>Bad file number Mon Mar
> 2 16:37:53 2009
>....
>....
>Bad file number Mon Mar
> 3 10:35:53 2009это не номально, и в каком именно месте это происходит в логе не пишется. как анализировать?
>Ещё вопрос, мне рекомендуют использовать неблокированный режим сокета, на сколько это оправдано
>и нет ли понятного примера реализации...?не оправдано.
решение с select() гораздо лучше.
пример есть в man select.
>я честно говоря первый раз пишу на Си да ещё и под Unix... Но
>очень хочу написать)))
>А еще открытое соединение нужно закрывать
http://www.rsdn.ru/Forum/Info.aspx?name=FAQ.network.socket.w...
"3. shutdown(), close() и closesocket()"
Может не в том причина нестабильности, но лишним точно не будет.