-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtcp_servidor_fork.c
More file actions
135 lines (107 loc) · 2.69 KB
/
Copy pathtcp_servidor_fork.c
File metadata and controls
135 lines (107 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#define P_SIZE sizeof(struct psuma)
struct psuma {
uint16_t v1;
uint16_t v2;
uint32_t res;
};
void terminar_hijo (int sig) {
int pid, res;
(void)sig; // Evitar advertencia de parámetro no usado
while ( (pid = waitpid ( -1 , &res, WNOHANG )) > 0 ) {
printf ("Termino el proceso %d con resultado %d\n", pid, res);
}
}
// Función que se encarga de leer un mensaje de aplicacion completo
// lee exactamente la cantidad de bytes que se pasan en el argumento total:
int leer_mensaje ( int sd, char * buffer, int total ) {
int bytes;
int leido;
leido = 0;
bytes = 1;
while ( (leido < total) && (bytes > 0) ) {
bytes = recv ( sd , buffer + leido , total - leido , 0);
if (bytes < 0) {
return -1;
}
leido = leido + bytes;
}
return ( leido );
}
int main() {
int n;
int sd;
int sdc;
socklen_t lon;
int pid;
char buffer[P_SIZE];
struct sockaddr_in servidor;
struct sockaddr_in cliente;
struct psuma *suma;
signal ( SIGCHLD , terminar_hijo );
servidor.sin_family = AF_INET;
servidor.sin_port = htons(4444);
servidor.sin_addr.s_addr = INADDR_ANY;
sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd < 0) {
perror("Error al crear el socket");
exit(-1);
}
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0) {
perror("setsockopt(SO_REUSEADDR) failed");
close(sd);
exit(-1);
}
if (bind(sd, (struct sockaddr *) &servidor, sizeof(servidor)) < 0) {
perror("Error en bind");
close(sd);
exit(-1);
}
listen ( sd , 5 );
while (1) {
lon = sizeof(cliente);
sdc = accept ( sd, (struct sockaddr *) &cliente, &lon );
if (sdc < 0) {
if (errno == EINTR) {
continue;
}
perror("Error en accept");
continue;
}
pid = fork();
if (pid < 0) {
perror("Error en fork");
close(sdc);
continue;
}
if (pid == 0) {
close (sd);
while ( ( n = leer_mensaje ( sdc , buffer , P_SIZE ) ) > 0 ) {
suma = (struct psuma *) buffer;
printf("Recibí desde: %s puerto: %d los valores: v1 %d v2 %d res %d \n", inet_ntoa(cliente.sin_addr), ntohs( cliente.sin_port), ntohs(suma->v1), ntohs(suma->v2), ntohl(suma->res));
suma->res = htonl(ntohs(suma->v1) + ntohs(suma->v2));
printf("Enviando: v1 %d v2 %d res %d \n", ntohs(suma->v1), ntohs(suma->v2), ntohl(suma->res));
if (send ( sdc , buffer, P_SIZE, 0 ) < 0) {
perror("Error en send");
break;
}
}
close (sdc);
exit (0);
} else {
printf("Se creo el proceso %d\n",pid);
close (sdc);
}
}
close(sd);
}