多线程和套接字/TCP [VB.NET]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16788666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MultiThreading and Sockets/TCP [VB.NET]
提问by Frederic Daniel
I started learning about TCP/Sockets yesterday and decided to make a chatbox for a friend and I.
我昨天开始学习 TCP/Sockets 并决定为我和我的朋友制作一个聊天框。
Unfortunately, i am having some difficulties with MultiThreading.
不幸的是,我在使用多线程时遇到了一些困难。
Whenever i am using it, i can no longer receive messages from my friend.
每当我使用它时,我就无法再收到朋友的消息。
But, if i disable it then, everything works perfectly.
但是,如果我当时禁用它,一切正常。
I don't know what's going on here, could somebody help?
我不知道这里发生了什么,有人可以帮忙吗?
Imports System.Net.Sockets
Imports System.Net
Public Class ServerClient
Dim _TCPServer As Socket
Dim _TCPListener As TcpListener
Dim _ListenerThread As System.Threading.Thread
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
'When Submit is pressed, send some text to the client
Dim bytes() As Byte = System.Text.Encoding.ASCII.GetBytes(txtInput.Text)
txtBox.AppendText(vbCrLf & "Server: " & txtInput.Text)
txtInput.Clear()
_TCPServer.Send(bytes)
End Sub
Private Sub TCPListen()
'If somebody calls port 2424, accept it, unblock the socket and start the timer
_TCPListener = New TcpListener(IPAddress.Any, 2424)
_TCPListener.Start()
_TCPServer = _TCPListener.AcceptSocket()
btnSend.Enabled = True
txtBox.AppendText("Connection Established" & vbCrLf)
_TCPServer.Blocking = False
_Timer.Enabled = True
End Sub
Private Sub _Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles _Timer.Tick
'If data has been sent, receive it
Try
Dim rcvdbytes(_TCPServer.ReceiveBufferSize) As Byte
_TCPServer.Receive(rcvdbytes)
txtBox.AppendText(vbCrLf & "Client: " & System.Text.Encoding.ASCII.GetString(rcvdbytes) & vbCrLf)
Catch ex As Exception
End Try
End Sub
Private Sub ServerClient_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Link the new thread to TCPListen(), allow access to all threads and wait for a call
_ListenerThread = New Threading.Thread(AddressOf TCPListen)
Control.CheckForIllegalCrossThreadCalls = False
txtBox.AppendText("Waiting for connection.." & vbCrLf)
btnSend.Enabled = False
_ListenerThread.Start()
End Sub
End Class
回答by Aditya Patil
This example project contains four classes - TcpCommServer, TcpCommClient, clsAsyncUnbuffWriter and CpuMonitor. With these classes, you will not only be able to instantly add TCP/IP functionality to your VB.NET applications, but also has most of the bells and whistles we're all looking for. With these classes, you will be able to connect multiple clients to the server on the same port. You will be able to easily: throttle bandwidth to the clients, and send and receive files and data (text?) along 250 provided channels simultaneously on a single connection.
此示例项目包含四个类 - TcpCommServer、TcpCommClient、clsAsyncUnbuffWriter 和 CpuMonitor。使用这些类,您不仅可以立即将 TCP/IP 功能添加到您的 VB.NET 应用程序中,而且还拥有我们一直在寻找的大多数花里胡哨的功能。使用这些类,您将能够将多个客户端连接到同一端口上的服务器。您将能够轻松地:限制客户端的带宽,并在单个连接上沿 250 个提供的通道同时发送和接收文件和数据(文本?)。
http://www.codeproject.com/Articles/307315/Reusable-multithreaded-tcp-client-and-server-class
http://www.codeproject.com/Articles/307315/Reusable-multithreaded-tcp-client-and-server-class
回答by Frederic Daniel
Well, i learned BackgroundWorkers could do the exact same thing and now it all works.
好吧,我了解到 BackgroundWorkers 可以做完全相同的事情,现在一切正常。
Private Sub ServerClient_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Wait for a call
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
TCPListen()
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
_Timer.Enabled = True
End Sub

