-
Notifications
You must be signed in to change notification settings - Fork 0
/
Server.go
179 lines (149 loc) · 3.87 KB
/
Server.go
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package main
import (
"bufio"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"strings"
"time"
)
var logger *log.Logger
const BUFFERSIZE = 1024
func enviarArchivo (conn net.Conn, in *bufio.Reader, srcFile string, nCLiente int) bool {
defer conn.Close()
// Abre el archivo a enviar
arch, err := os.Open(srcFile)
if err != nil {
logger.Println("Hubo un error: ", err, " al abrir el archivo para enviar al cliente ", nCLiente)
return false
}
defer arch.Close()
hash := crearHash(arch)
if hash != "" {
// Abre de nuevo el archivo a enviar
arch, _ = os.Open(srcFile)
// Envía el archivo al cliente
info, err := arch.Stat()
if err != nil {
logger.Println("Hubo un error al sacar el tamaño del archivo ", err)
return false
}
// Esto se usa para llenar el buffer del cliente y que este no se quede esperando
tamanio := completarString(strconv.FormatInt(info.Size(), 10), 10)
logger.Println("Enviando el tamaño del archivo")
antes := time.Now()
conn.Write([]byte(tamanio))
buffer := make([]byte, BUFFERSIZE)
logger.Println("Empieza envío de archivo")
for {
_, err = arch.Read(buffer)
if err == io.EOF {
break
}
conn.Write(buffer)
}
msj0, err := in.ReadString('\n')
if err != nil {
logger.Println("Se produjo un error: ", err, "El cliente ", nCLiente, " no recibió el archivo")
return false
}
if msj0 == "OK" || msj0=="OK\n" {
fmt.Fprintln(conn, hash)
despues := time.Now()
seg := fmt.Sprintf("%f", despues.Sub(antes).Seconds())
logger.Println("Se envió el archivo al cliente ", strconv.Itoa(nCLiente), "y tardó ", seg, " segundos")
} else {
logger.Println("El cliente ", nCLiente, " no recibe el archivo")
return false
}
} else {
logger.Println("Hubo un error al calcular el hash y enviarlo al cliente ", nCLiente)
return false
}
msj, err := in.ReadString('\n')
msj3 := strings.TrimSuffix(msj, "\n")
if err != nil {
logger.Println("Se produjo un error: ", err, " y el cliente ", nCLiente, " no pudo verificar la integridad del archivo")
return false
} else if msj3 != "Verificado" {
logger.Println("El cliente ", nCLiente, " no pudo verificar la integridad del archivo")
return false
}
logger.Println("Se envió correctamente el archivo al cliente ", nCLiente)
return true
}
func completarString (retorno string, largo int) string {
for {
largoRetorno := len(retorno)
if largoRetorno < largo {
retorno = retorno + ":"
continue
}
break
}
return retorno
}
func crearHash (archivo *os.File) string {
// Crea una interfaz para realizar el hash
hash := md5.New()
// Copia el archivo a la interfaz
_, err := io.Copy(hash, archivo)
if err != nil {
return ""
}
// Obtiene el hash en 16 bytes
hashInBytes := hash.Sum(nil)[:16]
// Convierte el hash a String
return hex.EncodeToString(hashInBytes)
}
func main() {
logFile, err := os.Create("data/logServer.txt")
logger = log.New(logFile, ">>", log.LstdFlags)
logger.Println("Inicio")
fmt.Println("Indica el puerto en el que escuchar solicitudes")
var port string
fmt.Scanln(&port)
fmt.Print(port)
PORT := ":" + port
socket, err := net.Listen("tcp4", PORT)
if err != nil {
fmt.Println(err)
return
}
defer socket.Close()
fmt.Println("Ingrese qué video quiere enviar:\n(1) video1.mp4\n(2) video2.mp4")
var seleccion string
var archivo string
fmt.Scanln(&seleccion)
if seleccion == "1" {
archivo = "data/video1.mp4"
} else {
archivo = "data/video2.mp4"
}
fmt.Println("Ingrese el número de usuarios que espera atender")
var numero int
fmt.Scanln(&numero)
i := 0
for {
conn, err := socket.Accept()
i ++
if err != nil {
fmt.Println(err)
return
}
inCliente := bufio.NewReader(conn)
msj1, err := inCliente.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
if msj1 == "Listo\n" || msj1 == "Listo" {
go enviarArchivo(conn, inCliente, archivo, i)
}
}
}