里面有文字的圆圈是州。文本描述了状态是什么。
虚线箭头指向起始状态。
传出箭头确定此状态可以更改的位置。箭头旁边是被线分为上半部分和下半部分的文本。下半部分是执行箭头转换时应该发生的动作。上半部分是条件。当它们为真时 - 执行此转换(以及下部)。
Lambda 符号意味着除了在转换发生时更改当前状态之外,您不应执行任何操作。
所以下面的部分有与你的功能相对应的粗略部分。上面的部分是您应该等待条件的点 - 轮询或异步等待挂起的 I/O 数据包,等等。
这是一些类似于 C 的伪代码(我只是在这里编写的,所以不要假设它可以工作,甚至可以编译):
enum State { WaitFor0Call, WaitForAck0, WaitForCall1, WaitForAck1 }
int main() {
State state = WaitFor0Call;
while (1) {
switch (state) {
case WaitFor0Call:
if (rdt_rcv(rcvpkt)) continue;
if (rdt_send(data)) {
state = WaitForAck0;
sndpkt = make_pkt(0, data, checksum);
udt_send(sndpkt);
start_timer();
}
break;
case WaitForAck0:
// ...similar code...
break;
case WaitForCall1:
// ...similar code...
break;
case WaitForAck1:
// ...similar code...
break;
}
}
}
您还应该考虑到接收和发送函数可能会阻塞,因此代码if (rdt_rcv(rcvpkt)) whatever;
从技术上讲是不正确的,因为您没有检查rdt_send
直到它返回控制权。因此,FSM 仅传达逻辑流程,而不传达如何组织、线程管理等技术方面的信息。我的代码也没有显示这些方面,因为根据您的需求,它可能会相当复杂,而且您没有提供足够的详细信息就此类事情提出明智的建议:)
我唯一的猜测是你会有某种双向流(分别用于输入和输出)并且条件如下if (there_is_ready_for_consuming_packet_in_the_input_queue) continue;
and if (data_was_put_to_outgoing_stream_successfully) ...;