本程序演示了TCP应答窗口的工作原理。
Public Class Form1
Const POS_TOP = 32
Const POS_BOTT = 200
Const TMR_MAX = 2000
Const POS_WIDTH = 20
Const POS_WIDTHW = 24
Dim POS_STEP As Integer
Dim TXWin As Integer
Dim RXWin As Integer
Dim WinSize As Integer
Dim WinsizeR As Integer
Dim Pkg_RcvR(20) As Integer
Dim Pkg_RcvT(20) As Integer
Dim Pkg_Sent(20) As Integer
Dim TopLabel() As Label
Dim BottomLabel() As Label
Dim PkgLabel() As Label
Dim TmrLabel() As Label
Dim Pkg_Dir(20) As Integer '数据包运动方向变量
Dim Tmr_Cnt(20) As Integer '数据包超时计数
Dim Lab_Dir As Boolean
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmr_Global.Tick
Dim i As Integer
For i = 1 To 20
If Pkg_Dir(i) = 1 Then PkgLabel(i).Top = PkgLabel(i).Top + POS_STEP
If Pkg_Dir(i) = -1 Then PkgLabel(i).Top = PkgLabel(i).Top - POS_STEP
If PkgLabel(i).Top >= POS_BOTT Then
If i < RXWin Or i >= RXWin + WinsizeR Then
Pkg_Dir(i) = 0
PkgLabel(i).Visible = False
PkgLabel(i).Top = POS_TOP
Else
Pkg_Dir(i) = -1
PkgLabel(i).BackColor = Color.Yellow
BottomLabel(i).BackColor = Color.Yellow
PkgLabel(i).Top = POS_BOTT
Pkg_RcvR(i) = 1
End If
End If
If PkgLabel(i).Top <= POS_TOP And Pkg_Dir(i) = -1 Then
Pkg_Dir(i) = 0
PkgLabel(i).Visible = False
If i < TXWin Or i >= TXWin + WinSize Then
'TopLabel(i).BackColor = Color.White
Else
TopLabel(i).BackColor = Color.Red
PkgLabel(i).Top = POS_TOP
Pkg_RcvT(i) = 1
End If
End If
If Pkg_RcvT(i) = 0 Then Tmr_Cnt(i) = Tmr_Cnt(i) - 3
If (Tmr_Cnt(i) <= 0) Then
Tmr_Cnt(i) = 0
If (Pkg_RcvT(i) = 0 And Pkg_Sent(i) = 1) Then
Pkg_Dir(i) = 1
PkgLabel(i).Top = POS_TOP
PkgLabel(i).BackColor = Color.Red
PkgLabel(i).Visible = True
Tmr_Cnt(i) = TMR_MAX
Beep()
End If
End If
TmrLabel(i).Text = Int(Tmr_Cnt(i) / 100)
Next
For i = 1 To 20
If Pkg_RcvT(i) = 0 Then Exit For
Next
TXWin = i
ShowLabel1(TXWin)
For i = 1 To 20
If Pkg_RcvR(i) = 0 Then Exit For
Next
RXWin = i
ShowLabel2(RXWin)
TextBox1.Text = "T:" & TXWin
TextBox2.Text = "R:" & RXWin
If (TXWin >= 21) Then
tmr_Global.Enabled = False
btnSend.Enabled = False
btnPause.Enabled = False
btnKill.Enabled = False
MsgBox("所有的数据都已成功发送完毕并收到应答。", MsgBoxStyle.Information, "恭喜你")
End If
End Sub
Private Sub PkgLabel_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim i As Integer
For i = 1 To 20
If sender.Equals(PkgLabel(i)) = True Then
PkgLabel(i).BackColor = Color.Cyan
End If
Next
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As New Integer
ReDim TopLabel(20)
ReDim BottomLabel(20)
ReDim PkgLabel(20)
ReDim TmrLabel(20)
POS_STEP = 1
For i = 1 To 20
PkgLabel(i) = New Label
TopLabel(i) = New Label
BottomLabel(i) = New Label
PkgLabel(i).Left = POS_WIDTHW * i
PkgLabel(i).Width = POS_WIDTH
PkgLabel(i).Height = 16
PkgLabel(i).BorderStyle = BorderStyle.FixedSingle
AddHandler PkgLabel(i).Click, AddressOf PkgLabel_Click
TmrLabel(i) = New Label
TmrLabel(i).Left = POS_WIDTHW * i
TmrLabel(i).Top = 12
TmrLabel(i).Width = POS_WIDTH
TmrLabel(i).Height = 16
TmrLabel(i).BackColor = Color.White
TmrLabel(i).BorderStyle = BorderStyle.FixedSingle
TopLabel(i).Left = POS_WIDTHW * i
TopLabel(i).Top = POS_TOP
TopLabel(i).Width = POS_WIDTH
TopLabel(i).Height = 16
TopLabel(i).BorderStyle = BorderStyle.FixedSingle
BottomLabel(i).Left = POS_WIDTHW * i
BottomLabel(i).Top = POS_BOTT
BottomLabel(i).Width = POS_WIDTH
BottomLabel(i).Height = 16
BottomLabel(i).BorderStyle = BorderStyle.FixedSingle
Me.Controls.Add(PkgLabel(i))
Me.Controls.Add(TmrLabel(i))
Me.Controls.Add(TopLabel(i))
Me.Controls.Add(BottomLabel(i))
Next
Reset_All()
End Sub
Private Sub Reset_All()
Dim i As Integer
TXWin = 1
RXWin = 1
For i = 1 To 20
Pkg_RcvR(i) = 0
Pkg_RcvT(i) = 0
Pkg_Sent(i) = 0
Pkg_Dir(i) = 0
Tmr_Cnt(i) = 0
PkgLabel(i).Top = POS_TOP
PkgLabel(i).BackColor = Color.Red
PkgLabel(i).Visible = False
TopLabel(i).BackColor = Color.White
BottomLabel(i).BackColor = Color.Blue
WinSize = Num1.Value
WinsizeR = Num2.Value
Next
ShowLabel1(1)
ShowLabel2(1)
Label1.SendToBack()
Label2.SendToBack()
tmr_Global.Enabled = True
btnPause.Text = "暂停(&P)"
Num2.Enabled = True
btnSend.Enabled = True
btnPause.Enabled = True
btnKill.Enabled = True
End Sub
Private Sub ShowLabel1(ByVal i As Integer)
If (i - 1 + WinSize > 20) Then
Label1.Width = POS_WIDTHW * (20 - i + 1)
Else
Label1.Width = POS_WIDTHW * WinSize
End If
Label1.Left = TopLabel(1).Left - (POS_WIDTHW - POS_WIDTH) / 2 + POS_WIDTHW * (i - 1)
Label1.Top = POS_TOP - 2
Label1.Height = TopLabel(1).Height + 4
End Sub
Private Sub ShowLabel2(ByVal i As Integer)
If (i - 1 + WinsizeR > 20) Then
Label2.Width = POS_WIDTHW * (20 - i + 1)
Else
Label2.Width = POS_WIDTHW * WinsizeR
End If
Label2.Left = TopLabel(1).Left - (POS_WIDTHW - POS_WIDTH) / 2 + POS_WIDTHW * (i - 1)
Label2.Top = POS_BOTT - 2
Label2.Height = TopLabel(1).Height + 4
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPause.Click
If tmr_Global.Enabled = False Then
tmr_Global.Enabled = True
btnPause.Text = "暂停(&P)"
Else
tmr_Global.Enabled = False
btnPause.Text = "继续(&C)"
End If
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Dim i As Integer
Num2.Enabled = False
For i = 1 To WinSize
If (TXWin + i - 1 > 20) Then Exit For
If (Pkg_Dir(TXWin + i - 1) <> 0 Or Pkg_RcvT(TXWin + i - 1) = 1 Or Tmr_Cnt(TXWin + i - 1) > 0) Then
Else
PkgLabel(TXWin + i - 1).Visible = True
Pkg_Sent(TXWin + i - 1) = 1
Pkg_Dir(TXWin + i - 1) = 1
Tmr_Cnt(TXWin + i - 1) = TMR_MAX
Exit For
End If
Next
End Sub
Private Sub btnKill_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnKill.Click
Dim i As Integer
For i = 1 To 20
If (PkgLabel(i).BackColor = Color.Cyan) Then
Pkg_Dir(i) = 0
PkgLabel(i).Visible = False
PkgLabel(i).Top = POS_TOP
PkgLabel(i).BackColor = Color.Red
End If
Next
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
Reset_All()
End Sub
Private Sub Num1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Num1.ValueChanged
If (Num1.Value > 5) Then Num1.Value = 5
If (Num1.Value < 1) Then Num1.Value = 1
WinSize = Num1.Value
'ShowLabel1(1)
End Sub
Private Sub Num2_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Num2.ValueChanged
If (Num2.Value > 5) Then Num2.Value = 5
If (Num2.Value < 1) Then Num2.Value = 1
WinsizeR = Num2.Value
End Sub
End Class