Skip to content
Snippets Groups Projects
Commit 2533505f authored by MILON ETHAN's avatar MILON ETHAN
Browse files

refacto client

parent 16a47c40
Branches
No related merge requests found
Pipeline #107913 passed with stages
in 6 seconds
......@@ -7,7 +7,9 @@
#include <fcntl.h>
#include "utils/error.h"
#include "server/server.h"
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <assert.h>
......@@ -25,77 +27,88 @@ struct data {
* @param server
* @return int
*/
int send_data(uint16_t data, struct pollfd *fd_poll, int server)
int send_data(uint16_t data, int server)
{
uint16_t residue;
uint32_t ack;
uint32_t ack = 0;
// on calcule le crc
residue = crc_crc((uint8_t *)&(data), 2, &crc16_xmodem);
// on concatène la donnée et le crc dans une structure
struct data data_to_send = { data, htons(residue) };
struct data packet = { data, htons(residue) };
// on envoie la donnée et on attend un acquittement
// jusqu'à ce que le serveur renvoie un acquittement positif
do {
if (send(server, &data_to_send, sizeof(data_to_send), 0) <= 0)
while (__builtin_popcount(ack) < 16) {
ssize_t ret = send(server, &packet, sizeof(packet), 0);
if (ret == -1) {
PERROR("send");
return -1;
} else if (ret == 0) {
ERROR("Socket is closed");
return -1;
} else if (ret != sizeof(packet)) {
ERROR("send: partial write %zd/%lu", ret,
sizeof(packet));
return -1;
}
ret = recv(server, &ack, sizeof(ack), 0);
if (ret == -1) {
PERROR("recv");
return -1;
} else if (ret == 0) {
ERROR("Socket is closed");
return -1;
} else if (ret != sizeof(ack)) {
ERROR("recv: partial read %zd/%lu", ret, sizeof(ack));
return -1;
CHK(poll(fd_poll, 1, -1));
if (fd_poll[0].revents != 0) {
CHK(recv(server, &ack, sizeof(ack), 0));
}
} while (
__builtin_popcount(ack) >
16); // il y a une chance infime que plus de 16 bits soient corrompus
return 1;
}
return 0;
}
int get_filesize(int fd)
{
struct stat statbuf;
CHK(fstat(fd, &statbuf));
return statbuf.st_size;
}
int main(int argc, char *argv[])
{
if (argc != 4)
BLAME("usage: %s <remote-host> <remote-port> <file>", argv[0]);
// initialisation
struct sockaddr_in addr;
int server;
if (argc != 4) {
BLAME("usage: %s <remote-host> <remote-port> <file>", argv[0]);
}
// mise en place de la connexion
if ((server = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
PERROR("socket");
return 1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[2]));
if (!inet_aton(argv[1], &addr.sin_addr))
if (inet_aton(argv[1], &addr.sin_addr) == 0)
BLAME("invalid remote host: %s", argv[1]);
if (connect(server, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(server);
PERROR("connect");
return 1;
}
struct pollfd fd_poll[1] = { { server, POLLIN, 0 } };
int server, fd;
// mise en place de la connexion
CHK(server = socket(AF_INET, SOCK_STREAM, 0));
CHK(connect(server, (struct sockaddr *)&addr, sizeof(addr)));
// envoi du fichier
int fd = open(argv[3], O_RDONLY);
if (fd < 0) {
PERROR("open");
return 1;
}
struct stat statbuf;
CHK(fstat(fd, &statbuf));
uint16_t data;
// ouverture du fichier
CHK(fd = open(argv[3], O_RDONLY));
int size = get_filesize(fd);
// envoi de si la taille est paire ou impaire
// pour la dernière donnée (car on envoie 2 octets à la fois)
CHK(send_data((uint16_t)statbuf.st_size % 2, fd_poll, server));
CHK(send_data(size % 2, server));
// envoi des données
int size = (int)(statbuf.st_size / sizeof(data) +
statbuf.st_size % sizeof(data));
for (int i = 0; i < size; i++) {
CHK(read(fd, &data, sizeof(data)));
CHK(send_data(data, fd_poll, server));
uint16_t data;
if (read(fd, &data, sizeof(data)) != sizeof(data))
return EXIT_FAILURE;
if (send_data(data, server) < 0)
return EXIT_FAILURE;
}
printf("transfert terminé\n");
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment