]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/devque.cpp
Se agrega opción para recibir paquetes de un host específico y se mejora el
[z.facultad/75.74/practicos.git] / practicas / pipi / src / devque.cpp
1 #include "devque.h"
2 #include <cstring>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #ifdef DEBUG
9 #include <iostream>
10 #endif
11
12 struct Frame
13 {
14     Dev::mac_type mac;
15     size_t size;
16     char frame[1];
17 };
18
19 DevQue::DevQue(mac_type mac, key_t key, size_t mtu)
20     throw (std::runtime_error, std::logic_error):
21         Dev(mac, mtu)
22 {
23     que_id = msgget(key, 0666); // Debe estar previamente creada
24     if (que_id == -1)
25         throw std::runtime_error("No se pudo crear la cola");
26 }
27
28 void DevQue::transmit(const std::string& data, const mac_type& mac)
29     throw (std::runtime_error, std::logic_error)
30 {
31     if (data.size() > mtu)
32         throw std::logic_error("Tamaño de datos mayor al MTU");
33     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
34     if (!f)
35         throw std::runtime_error("No se puede reservar memoria");
36     f->mac = mac;
37     f->size = data.size();
38     memcpy(f->frame, data.c_str(), data.size());
39     int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0);
40 #ifdef DEBUG2
41     std::cout << "DevQue::transmit(msgtype/mac = " << f->mac << ", size = "
42         << f->size << ")\n";
43 #endif
44     free(f);
45     if (res == -1)
46         throw std::runtime_error("Error al poner en la cola");
47 }
48
49 std::string DevQue::receive() throw (std::runtime_error)
50 {
51     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
52     if (!f)
53         throw std::runtime_error("No se puede reservar memoria");
54     int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0);
55     if (res == -1)
56     {
57         free(f);
58         throw std::runtime_error("Error al sacar de la cola");
59     }
60     std::string s((char*) f->frame, f->size);
61     free(f);
62 #ifdef DEBUG2
63     std::cout << "DevQue::receive(msgtype/mac = " << mac << ", size = "
64         << s.size() << ")\n";
65 #endif
66     return s;
67 }
68
69 // vim: set et sw=4 sts=4 :