如何使TCPClient完全可重用 [英] How to make TCPClients FULLY reusable

查看:135
本文介绍了如何使TCPClient完全可重用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,



我想有一个程序允许我通过tcp连接到同一程序的另一个实例,发送尽可能多的消息想要,断开连接,再次重新连接并继续这样(完全可重复使用)。我有这个代码:



Hello,

I'd like to have a program which allows me to connect via tcp to another instance of the same program, send as many messages as I want, disconnect, reconnect again and continue on as such (fully reusable). I have this code:

Imports System.Net.Sockets
Imports System.Threading
Imports System.Runtime.Serialization.Formatters.Binary
Public Class Form1
    Dim Client As TcpClient
    Dim Server As TcpListener
    Dim Listening As New Thread(AddressOf Listen)
    Dim GetMessage As New Thread(AddressOf ReceiveMessage)
    Dim BF As New BinaryFormatter
    Private Sub ReceiveMessage()
        While Client.Connected = True
            ListBox1.Items.Add("RECEIVED: " & BF.Deserialize(Client.GetStream))
        End While
    End Sub
    Private Sub Listen()
        While Client.Connected = False
            Server.Start()
            Client = Server.AcceptTcpClient
        End While
        GetMessage.Start()
    End Sub
    Dim ReceivingPort As Integer
    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        Client.Client.Close()
        Server.Server.Close()
    End Sub
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim r As New Random
        ReceivingPort = r.Next(50000, 60000)
        Me.Text = ReceivingPort
        MakeNewClient()
        MakeNewReceiver()
    End Sub
    Private Sub MakeNewClient()
        Try
            Client.Client.Close()
        Catch ex As Exception

        End Try
        Client = New TcpClient
        ListBox1.Items.Add("INFO: New client created")
    End Sub
    Private Sub MakeNewReceiver()
        Try
            Listening.Abort()
            GetMessage.Abort()
            Server.Server.Close()
        Catch ex As Exception

        End Try
        Server = New TcpListener(ReceivingPort)
        Listening = New Thread(AddressOf Listen)
        GetMessage = New Thread(AddressOf ReceiveMessage)
        Listening.Start()
        ListBox1.Items.Add("INFO: New receiver created")
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            Client.Connect(TextBox2.Text, TextBox3.Text)
            ListBox1.Items.Add("SUCCESS: Connected")
        Catch ex As Exception
            ListBox1.Items.Add("ERROR: Could not connect" & vbNewLine & vbNewLine & ex.Message)
        End Try
    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Try
            BF.Serialize(Client.GetStream, TextBox1.Text)
            ListBox1.Items.Add("SENT: " & TextBox1.Text)
        Catch ex As Exception
            ListBox1.Items.Add("ERROR: Could not send message" & vbNewLine & vbNewLine & ex.Message)
        End Try
    End Sub
End Class





目前,消息只能以一种方式发送,但我无法弄清楚原因。我认为通过TCP连接,只需要一个连接就可以以任何方式发送消息。



如果有人能指出我哪里出错了我很感激。



-Rixterz



At the moment, messages can only be sent one way but I cannot figure out why. I thought that with a TCP connection, only one connection needs to be made for messages to be sent either way.

If anyone can point out where I've gone wrong I'd appreciate it.

-Rixterz

推荐答案

已经存在完全可重用的类:

System.Net.Sockets.TcpListener

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener%28v = vs.110%29.aspx [ ^ ];

System.Net.Sockets.TcpClient

http: //msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient%28v=vs.110%29.aspx [ ^ ]。



他们很好地匹配您的描述。难怪,使用这些类的任何合理代码都会创建更多专门的场景。这不合逻辑吗?



所以,我们不要讨论完全可重复使用这个相当不确定的术语。更好地考虑你更专业的案例。如何提高其可重用性?首先,创建一些完全与UI隔离的类。单独的客户端和服务器部分(我真的不明白你为什么要混合它们;你可能有你的理由,我不知道。)怎么样?例如,摆脱按钮单击处理程序。如果可能只是你的类的一个方法(派生自 System.Object ,而不是 Form )。您在连接客户端时显示某些内容。需要以通用的方式处理它吗?创建一个事件实例。使用您的类的代码将需要向事件的调用列表添加处理程序(使用为所有事件定义的+ =运算符)。等等......



更重要的方面是:你需要在服务器端至少有两个通信线程:一个侦听新连接,另一个读取/写入/到网络流。客户端需要另一个,只需一个独立的线程。所有这些线程都应该是非UI线程。在哪里实现UI线程的委托?只有使用您的通信类的代码才能在它安装的处理程序中执行此操作。为什么?因为您的类应该不可知到UI。因此,您可以使用许多其他UI库:WPF,Silverlight,Metro等。



有关更多详细信息,请参阅我过去的答案:

同一端口号码的多个客户端 [< a href =http://www.codeproject.com/Answers/165297/Multple-clients-from-same-port-Number#answer1target =_ blanktitle =New Window> ^ ] ,

套接字编程中的业余问题 [ ^ ]。



-SA
The fully reusable classes already exist:
System.Net.Sockets.TcpListener:
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener%28v=vs.110%29.aspx[^];
System.Net.Sockets.TcpClient:
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient%28v=vs.110%29.aspx[^].

They matche your description pretty well. No wonder, any reasonable code using these classes creates some more specialized scenario. Isn't that logical?

So, let's not discuss as a rather uncertain term as "fully reusable". Better think of your more specialized case. How can you improve its reusability? Fist and foremost, create some class totally isolated from UI. Separate client and server parts (I don't really understand why do you mix them; you might have your reasons, I don't know.) How? For example, get rid of the button click handler. If could be just a method of your class (derived from System.Object, not Form). You show something when a client is connected. Need to handle it in a universal way? Create an event instance. The code using your class will need to add a handler to the invocation list of the event (using the += operator defined for all events). And so on…

More essential aspect is: you need to have at least two communication threads on server side: one listens for new connections, another one reading/writing from/to the network stream. A client need another, just one, separate thread. All those threads should be non-UI threads. Where to implement the delegation to the UI thread? Only the code using your communication class(es) should do it, in the handler it installs. Why? Because your class(es) should be agnostic to UI. So you could work with many other UI libraries: WPF, Silverlight, Metro, and more.

For some more detail, please see my past answers:
Multple clients from same port Number[^],
an amateur question in socket programming[^].

—SA


这篇关于如何使TCPClient完全可重用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆