我有一项任务,我必须实施一些网络协议。分配包括通过理想连接(不丢失或损坏数据)的通信和破坏数据的连接。我想尽可能地将其作为模块化,但我无法弄清楚如何做到这一切(一切似乎都交织在一起)。这是我要做的事情清单:
也许我可以实现分层架构(受OSI模型的启发),但我不知道该怎么做。我需要在正确的方向上轻推。
这些不同的模块应该如何相互作用?这样的Go-Back-N或Selective Repeat功能与我是否想要填充数据链接(滑动窗口)无关,并且在所有这些之上进行错误检查是透明的。
编辑:另一个难点是某些协议(Go-Back-N,Selective Repeat,Sliding Window)需要特定于该协议的状态,并且没有很好的方法在C中实现有状态函数。
答案 0 :(得分:2)
也许你可以使用链式函数?
最初,您可以拥有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
等字段。首先,您将使用处理理想连接的函数填充它。
然后,要添加滑动窗口,您可以使用struct sliding_window_connection
中要截取的所有字段struct connection
。然后,您将旧的函数和数据指针从struct connection
移动到struct sliding_window_connection
,用滑动窗口实现替换struct connection
中的函数,并替换{中的数据指针{1}}指向struct connection
的指针。新的struct sliding_window_connection
可以是例如看起来有点像这样:
write
为了在顶部堆叠go-back-n或选择性重复,您可以以相同的方式添加go-back-n或选择性重复功能。
对于阅读,您基本上也会这样做 - 让数据在图层中冒泡,并可能在途中操纵或解释它。
为了使这项工作更好,你可能想要添加一个类似于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);
}
的函数,它可以被一个层(例如go-back-n)用来发信号通知下层(例如滑动窗口)像“嘿,请重新发送字节m-> n,谢谢”。
由于错误检测必须在比这些事情更高的层次上发生,你必须在其他事情之后添加它 - 你添加的东西越晚,它的层越高。