也许你可以使用链式函数?
最初,您可以使用、和等struct connection
字段。首先,您将使用处理理想连接的函数来填充它。void (*write)(struct connection *con, char *buf, size_t len, void *data);
void *write_data;
int (*get_write_queue_size)(struct connection *con, void *data)
void *get_write_queue_size_data
Then, for adding a sliding window, you would make a struct sliding_window_connection
with all the fields from struct connection
that you want to intercept. Then, you would move the old functions and data-pointers from the struct connection
into the struct sliding_window_connection
, replace the functions in the struct connection
with the sliding window implementations and replace the data pointers in the struct connection
with pointers to the struct sliding_window_connection
. The new write
could e.g. look somewhat like this:
void sliding_window_connection_write
(struct connection *con, char *buf, size_t len, void *data) {
struct sliding_window_connection *swcon = data;
/* ... do magic for the sliding window ... */
/* if we want the buffer to be sent now, call the lower layer like this: */
swcon->write(con, buf, len, swcon->write_data);
}
For stacking go-back-n or selective repeat on top, you would then add the go-back-n or selective repeat functions the same way.
For reading, you would basically do the same – let the data bubble up through the layers and maybe manipulate or interpret it on the way.
To make this work better, you might want to add a function similar to write
that can be used by a layer (e.g. go-back-n) to signal a lower layer (e.g. the sliding window) for purposes like "hey, please resend bytes m->n, thanks".
As error detection would have to happen on a higher level than these things, you would have to add it after the other things – the later you add something, the higher its layer.