/* Daytime Daemon
@2000 Helder Daniel
formato de linha de comando: dtd <maximo de conexoes concorrentes> <porto>
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <errno.h>
int Numproc=0;
void end_child(int s)
{
/* Suspende a execuçao do processo corrente, ate que um filho especificado
pelo 1º parametro termine. Se este valor for 0 espera por qualquer processo
do mesmo grupo. O 2º parametro indica onde a funçao pode guardar informacao
sobre o estado da termincao do processo especificado no 1º parametro.
O 3º parametro WNOHANG indica que waitpid retorna imediatamente se nenhum
filho esta a terminar ou Zombie. Neste caso, waitpid, retorna zero, se
existir um erro retorna -1, e em qualquer outro caso o PID do filho que terminou.
*/
if (waitpid(0, NULL, WNOHANG)>0) Numproc--;
else signal (SIGCHLD, end_child);
/* Se nao existir nenhum filho a terminar ou Zombie ou se ocorreu um erro com
waitpid sera necessario restabelecer este manipulador
*/
}
void killsocket(int s, char *m)
{
perror(m); /* Imprime mensagem de erro */
shutdown(s, 2); /* Desliga a conexao full-duplex associada com o socket s.
2 -> recusar futuros sends e receives */
exit (-1);
}
void sendinfo(int s, FILE *out)
{
char *buf;
time_t t;
t = time(NULL);
if (t==-1) fprintf(out, "%s\n", strerror(errno));
fprintf(out, "%s", ctime(&t));
fclose (out);
}
main(int argc, char **argv)
{
int port;
int maxproc;
int sock, csock;
int n;
struct sockaddr_in server, client;
int lc= sizeof(client);
FILE *io;
/* Valida linha de comandos
*/
if (argc!=3)
{
puts("formato de linha de comando:\n"
"dtd <maximo de conexoes concorrentes> <porto>");
exit(-1);
}
if (atoi(*(argv+1))<1 || atoi(*(argv+1))>25)
{
puts("Conexoes suportadas 1 - 25.\n");
exit(-1);
}
else maxproc=atoi(*(argv+1));
if (atoi(*(argv+2))<1024 || atoi(*(argv+2))>65535)
{
puts("Portos possiveis: 1024 - 65535\n");
exit(-1);
}
else port=atoi(*(argv+2));
/* cria o socket sock, para internet, orientado para a ligaçao (tipo stream)
*/
if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) //start server socket TCP socket
{
perror("Impossivel criar socket!");
exit(-1);
}
/* Habilita reutilizaçao do endereço local
(n=1 enable option; n=0 disable option)
*/
n=1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n))==-1) //Socker reutilizavel, mais do que um cliente
killsocket (sock, "Impossivel seleccionar opcçoes do socket");
/* Preenche a estrutura server com zeros
*/
memset(&server, 0, sizeof(server));
/* Define o endereço local server
*/
server.sin_family=AF_INET; /* Suporta familia de endereços internet */
server.sin_addr.s_addr=htonl(INADDR_ANY); /* Aceita qualquer endereço de ligaçao */
server.sin_port=htons(port); /* Porto > 1023 e < 65535 */
/* Atribui ao socket sock o endereço local server, o qual identifica o servidor
*/
if (bind(sock, (struct sockaddr *) &server, sizeof(server))==-1)
killsocket (sock, "Impossivel atribuir endereço local ao socket");
/* Activa a fila de espera de coneçoes, para o socket sock, e limita-a a 5 coneçoes
*/
if (listen(sock, 5)==-1) //qeue de 5, nao passa daqui ate que um cliente se conecte
killsocket (sock, "Impossivel reservar fila de coneçoes para o socket");
/* Socket criado com sucesso */
/* Processo corrente lança um filho e termina. O pai do filho passa a ser o init.
Seguidamente o Daemon fecha os canais de comunicaçao com a consola.
Assim cria-se um daemon (em DOS chama-se TSR)
*/
if (fork()!=0) exit(0);
close(stdin);
close(stdout);
/* Define a rotina para tratamento do fim de um filho
*/
signal (SIGCHLD, end_child);
/* Ignora o sinal SIGHUP, ou seja evita terminar o processo corrente se o terminal
que o lançou for fechado ou se o processo que o controla for morto
*/
signal (SIGHUP, SIG_IGN);
/* Ciclo principal
Escuta pedidos e trata-os
*/
for (;;)
{
if (Numproc <= maxproc)
{
/* Retira a primeira conecçao da fila de listen.
accept cria um novo socket com as mesmas propriedades de sock e retorna
um descritor para o novo socket (csock), ou -1 se nao existir nenhuma
conecçao na fila de espera. Em client e guardado o endereco do cliente a servir.
*/
do
{
csock=accept (sock, (struct sockaddr *)&client, &lc);
}
while (csock==-1);
/* Cria filho para atender o pedido
*/
if (csock==-1) sleep (1); /* Erro na abertura do sockect para cliente */
else
{
Numproc++;
switch(fork())
{
/* Filho atende pedido */
case 0:
/* Fecha descritor nao necessario de socket */
close (sock);
/* associa um stream com o descriptor para o cliente */
if ((io = fdopen(csock, "r+"))!=NULL)
{
/* Manipulador */
sendinfo(csock, io);
/* descarrega buffers antes de terminar filho */
fflush (io);
}
/* Termina filho depois de atender o pedido */
exit (0);
/* Erro na criaçao do filho */
case -1:
Numproc--;
close (csock);
break;
/* Se pai fechar csock pois o filho vai atender o pedido */
default:
close(csock);
} /* switch */
} /* else */
} /* if */
} /* for (;;) */
} /* main */
朱moyimi
- 粉丝: 78
- 资源: 1万+
最新资源
- 基于cruise的燃料电池功率跟随仿真,按照丰田氢能源车型搭建,在wltc工况下跟随效果好,最高车速175,最大爬坡30,百公里9s均已实现 1.模型通过cruise simulink联合仿真,策略
- C#源码 上位机 联合Visionpro 通用框架开发源码,已应用于多个项目,整套设备程序,可以根据需求编出来,具体Vpp功能自己编 程序包含功能 1.自动设置界面窗体个数及分布 2.照方式以命令触
- 程序名称:悬架设计计算程序 开发平台:基于matlab平台 计算内容:悬架偏频刚度挠度;螺旋弹簧,多片簧,少片簧,稳定杆,减震器的匹配计算;悬架垂向纵向侧向力学、纵倾、侧倾校核等;独立悬架杠杆比,等效
- 华为OD+真题及解析+智能驾驶
- jQuery信息提示插件
- 基于stm32的通信系统,sim800c与服务器通信,无线通信监测,远程定位,服务器通信系统,gps,sim800c,心率,温度,stm32 由STM32F103ZET6单片机核心板电路、DS18B2
- 充电器检测9-YOLO(v5至v11)、COCO、Create充电器检测9L、Paligemma、TFRecord、VOC数据集合集.rar
- 华为OD+考试真题+实现过程
- 保险箱检测51-YOLO(v5至v11)、COCO、CreateML、Paligemma、TFRecord、VOC数据集合集.rar
- 五相电机邻近四矢量SVPWM模型-MATLAB-Simulink仿真模型包括: (1)原理说明文档(重要):包括扇区判断、矢量作用时间计算、矢量作用顺序及切时间计算、PWM波的生成; (2)输出部分仿
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈