Написал tcp-сервак. Для каждого подключения я делаю fork и оно варится самостоятельно. После завершения сеанса - close(socket) и exit(0). Все хорошо, все работает, только после каждого коннекта к серваку, дочерние процессы переходят в состояние Z (зомби), а после окончания работы родителя - они пропадают. Кто-нибудь может обьяснить почему так происходит и как этого избежать. Система - Slackware 9.0.
Исходники:
"tcp_serv.c" :
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdarg.h>
#include<string.h>
#include<errno.h>
#include<netdb.h>
#include<fcntl.h>
#include<sys/time.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include "lib/skel.h"
main(int argc, char* argv[])
{
struct sockaddr_in peer;
int peerlen = sizeof(peer);
SOCKET s;
SOCKET ns;
int pid;
s = tcp_server(NULL, argv[1]);
while(1) {
ns = accept(s, (struct sockaddr *)&peer, &peerlen);
if (!isvalidsock(ns))
error(1, errno, "Ошибка вызова accept\n");
if ((pid=fork()) == -1)
error(1, errno, "Ошибка вызова fork\n");
if (pid==0) {
/* Дочерняя часть */
if (close(s))
error(1, errno, "Ошибка вызова close\n");
send(ns, "Hello world!\n", 13, 0);
if (close(ns))
error(1, errno, "Ошибка вызова close\n");
exit(0);
}
/* Родительская часть */
if (close(ns))
error(1, errno, "Ошибка вызова close\n");
}
exit(0);
}
"skel.h" :
#in#ifndef __SKEL_H__
#define __SKEL_H__ 1
#define FALSE 0
#define TRUE 1
#define NLISTEN 5
typedef int SOCKET;
#define set_errno(e) errno = (e)
#define isvalidsock(s) ( (s) >= 0 )
void error(int status, int err, char* format, ...);
static void set_address(char* hname, char* sname, struct sockaddr_in *sap, char* protocol);
SOCKET tcp_server(char* hname, char *sname);
void error(int status, int err, char* format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
if (err)
fprintf(stderr, "%s (%d)\n", strerror(err), err);
if (status)
exit(status);
}
static void set_address(char* hname, char* sname, struct sockaddr_in *sap, char* protocol)
{
struct servent* sp;
struct hostent* hp;
char* endptr;
short port;
bzero(sap, sizeof(*sap));
sap -> sin_family = AF_INET;
if (hname != NULL) {
if (!inet_aton(hname, &sap -> sin_addr)) {
hp = gethostbyname(hname);
if (hp == NULL)
error(1,0,"Неизвестный хост: %s\n", hname);
sap -> sin_addr = *(struct in_addr *)hp -> h_addr;
}
}
else
sap -> sin_addr.s_addr = htonl(INADDR_ANY);
port = strtol(sname, &endptr, 0);
if (*endptr == '\0')
sap -> sin_port = htons(port);
else {
sp = getservbyname(sname, protocol);
if (sp == NULL)
error(1,0,"Неизвестный сервис %s\n", sname);
sap -> sin_port = sp -> s_port;
}
}
SOCKET tcp_server(char* hname, char *sname)
{
struct sockaddr_in local;
SOCKET s;
const int on = 1;
set_address(hname, sname, &local, "tcp");
s = socket (AF_INET, SOCK_STREAM, 0);
if (!isvalidsock(s))
error(1, errno, "Ошибка вызова socket ");
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)))
error(1, errno, "Ошибка вызова setsockopt ");
if (bind(s, (struct sockaddr *)&local, sizeof(local)))
error(1, errno, "Ошибка вызова bind ");
if (listen(s, NLISTEN))
error(1, errno, "Ошибка вызова listen ");
return(s);
}
#endif /* __SKEL_H__ */
Ответ на:
комментарий
от Die-Hard
Ответ на:
комментарий
от Die-Hard
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум BROADCAST sendto вызывает Permission denied (2004)
- Форум Уничтожение дочернего процесса (2004)
- Форум Консольный обмен сообщениями (2017)
- Форум В чем ошибка чтения? (2020)
- Форум проблема с сокетами [C] (2009)
- Форум Помогите разобраться с потоками (2003)
- Форум [C] Получить данные на TCP сокет (2008)
- Форум [pthread][c][socket] recvfrom возвращает «bad file descriptor». (2011)
- Форум Accept блокирует работу (2017)
- Форум socket error (2009)