【发布时间】:2014-01-09 02:51:27
【问题描述】:
我开始构建 TCP 服务器/客户端及其协议,但它们是一些我无法理解的问题,因为它的文档较少,而且它也与跨线程有关。我也尽量避免非法的交叉线程。到目前为止,我在我的文本框上工作以更新 raiseStatus 事件的状态,无论如何我不知道如何使用列表框来做到这一点。通常我无法使用我这样构建的协议发送和接收我想要的所有消息:LOGIN:NAK。这意味着用户 NAK 登录,我的程序可以与此协议很好地通信,因为我还有更多要实现。我只是在客户端使用此命令时将 NAK 添加到 listbox1 时卡住了。
我的服务器端代码:
这是我的 form1 类
Public Class Form1
Dim portToListen As Integer = 700
Dim WithEvents manager As ClientMananger
Dim WithEvents M_Client As Client
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
manager = New ClientMananger(Me)
manager.Listen(portToListen)
End Sub
Private Sub manager_Status(message As String) Handles manager.Status
txtStatus.Text &= message & vbNewLine
End Sub
End Class
这是我的类 ClientManager
Public Class ClientMananger
Dim tcpListener As TcpListener
Dim listenThread As Thread
Dim clientList As New List(Of Client)
Public Event Status(message As String)
Public Event Connect(client As Client)
Public Event Disconnect(client As Client)
Public Sub Listen(port As Integer)
tcpListener = New TcpListener(port)
'' Start thread for listening for new income socket
listenThread = New Thread(AddressOf ListenProc)
listenThread.Start()
End Sub
Private Sub ListenProc()
RaiseStatus("Listen to port ...")
'' Continously listen to certain port
tcpListener.Start()
While True
Dim incomeClient As New Client(tcpListener.AcceptSocket(), Me)
'' Income connection has been made
RaiseStatus("Client attempt to connect ...")
'' Send welcome message to client
incomeClient.Send("Welcome to RAMA Hospital Chat Server!")
clientList.Add(incomeClient)
End While
End Sub
Public Sub SendAll(client As Client, msg As String)
For Each c As Client In clientList
If client IsNot c Then
c.Send(msg)
End If
Next
End Sub
Public Sub SendTo(sender As Client, rv As String, msg As String)
For Each c As Client In clientList
If c.name = rv Then
c.Send("PRIVATE:" & sender.name & ":" & msg)
End If
Next
End Sub
#Region "GUI"
Dim form As Form
'' GUI
Public Sub New(form As Form)
Me.form = form
End Sub
Private Sub RaiseStatus(txt As String)
form.Invoke(RaiseStatusInvoker, txt)
End Sub
Private Delegate Sub RaiseStatusDelegate(txt As String)
Private Sub RaiseStatusFunc(txt As String)
RaiseEvent Status(txt)
End Sub
Private RaiseStatusInvoker As New RaiseStatusDelegate(AddressOf RaiseStatusFunc)
#End Region
End Class
这是我无法使其工作的类客户端,无论如何我可以将我的 [part(1) 表示从客户端拆分的用户名] 部分 (1) 添加到 listbox1 吗?我使用了 form1.listbox1.item.add(part(1)) 但它不起作用它也没有显示任何错误。
Public Class Client
Dim sck As Socket
Dim msgThread As Thread
Public name As String = ""
Dim parent As ClientMananger
Private _socket As Socket
Private _client As Client
Public Event Status(message As String)
Public Sub New(sck As Socket, parent As ClientMananger)
Me.sck = sck
Me.parent = parent
'' Listen to incoming message
msgThread = New Thread(AddressOf ReceiveMessage)
msgThread.Start()
End Sub
Public Sub Send(message As String)
Dim msgByte() As Byte = System.Text.ASCIIEncoding.ASCII.GetBytes(message)
sck.Send(msgByte, SocketFlags.None)
End Sub
Private Sub ReceiveMessage()
Try
Dim buffer(1000) As Byte
Dim size As Integer = 0
Dim msg As String
Do
size = sck.Receive(buffer, SocketFlags.None)
If size > 0 Then
msg = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, size)
HandleMessage(msg)
End If
Loop While size > 0
Catch ex As SocketException
'' Disconnect
End Try
End Sub
Private Sub HandleMessage(msg As String)
Dim part() As String = msg.Split(":")
Dim command As String = part(0).ToUpper()
If command = "LOGIN" Then
Me.name = part(1)
**Form1.listbox1.item.add(part(1))**
MessageBox.Show(part(1) + " Had been add to the server!!!")
ElseIf command = "ALL" Then
parent.SendAll(Me, part(1))
ElseIf command = "PRIVATE" Then
parent.SendTo(Me, part(1), part(2))
End If
End Sub
End Class
很抱歉发布了很多代码,但真的无法完成这项工作,请提前帮助您,如果您想获得我的客户端代码,我可以在这里发布。
【问题讨论】:
标签: vb.net multithreading tcp network-programming