vb.net - 用于接收和发送的 udp 客户端不起作用

标签 vb.net sockets udp

我成功创建了一个 UDP 客户端-服务器连接并通过它发送了一个大图像。我将图像拆分并发送到每个 1500 字节的数据包中。我在另一端得到了 330025 字节的 353723(我认为这很好)。但是正如您所知,UDP 数据包不是按顺序排列的,所以我必须识别它发送的每个数据包(我不能使用 tcp,因为我的项目游戏需要速度)。现在我想向“服务器”询问丢失的数据包。

这是服务器的代码:

Imports System
Imports System.IO
Imports System.Net
Imports System.Threading
Imports System.Net.Sockets
Imports System.Text.Encoding


Public Class Form1
    Dim ep_client As New IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000)
    Dim ep_server As New IPEndPoint(IPAddress.Any, 60000)
    Dim publisher As New UdpClient(ep_client)


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Form2.Show()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim sendbytes() As Byte = ASCII.GetBytes(txt1.Text)
        Dim img As Image, img_stream As MemoryStream, buffer As Byte()
        Dim packet_size As Integer = 1024, sent_size As Long


        Try
            img_stream = imgToBytes(txt1.Text)

            Debug.Print(img_stream.Length)
            ReDim buffer(packet_size)

            While Not img_stream.Position = img_stream.Length
                sent_size += img_stream.Read(buffer, 0, packet_size)

                publisher.Send(buffer, buffer.Length)
            End While

            Debug.Print(100 * sent_size / img_stream.Length & "%")
        Catch ex As Exception
            Debug.Print(ex.Message)
        End Try

    End Sub


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        ''When I press this button it is supposed to 'listen'

        Try
            'Silence...Nothing here..
            publisher.BeginReceive(New AsyncCallback(AddressOf receive), publisher) 
            Debug.Print("listening")
        Catch ex As Exception
            Debug.Print(ex.Message)
        End Try


    End Sub
    Sub receive(ByVal ar As IAsyncResult)
        ''It should take the packets from coming from 'any' ip.

        publisher.EndReceive(ar, ep_server)

        Debug.Print("received")

        publisher.BeginReceive(New AsyncCallback(AddressOf receive), publisher)
    End Sub 



    Function imgToBytes(ByVal file_name As String) As MemoryStream
        Dim img As Image = Image.FromFile(file_name)
        Dim stream As New MemoryStream

        img.Save(stream, Drawing.Imaging.ImageFormat.Jpeg)
        stream.Position = 0

        Return stream
    End Function
End Class

这是客户端的代码(成为服务器...):
Imports System
Imports System.IO
Imports System.Net
Imports System.Threading
Imports System.Net.Sockets
Imports System.Text.Encoding


Public Class Form2
    Dim ep_server As IPEndPoint = New IPEndPoint(IPAddress.Any, 60000)
    Dim ep_client As New IPEndPoint(IPAddress.Parse("127.0.0.1"), 60000)

    Dim client As New UdpClient(ep_client)
    Dim stream As New MemoryStream



    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try

            'I belive it's listening for packets comming from ep_client ->
            'because I initialized the 'client' object with it
            'How can I make it listen for ep_server?(from all ip's)
            client.BeginReceive(New AsyncCallback(AddressOf receive), client)

        Catch ex As Exception
            Debug.Print(ex.Message)
        End Try
    End Sub

    Public Sub receive(ByVal ar As IAsyncResult)
        Dim buffer As Byte()

        Try
           'Now I use ep_server ->the proper way
            buffer = client.EndReceive(ar, ep_server)  
            stream.Write(buffer, 0, buffer.Length)

            client.BeginReceive(New AsyncCallback(AddressOf receive), client)

        Catch ex As Exception
            Debug.Print(ex.Message)
        End Try
    End Sub

    Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click
        Dim img As Image = Image.FromStream(stream)

        Debug.Print(stream.Length)
        PictureBox1.Image = img      ''Weird image because the packets are not arranged
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Debug.Print("sent")
        client.Send(ASCII.GetBytes("a"), 1, ep_client)   ''Send something ->not working
    End Sub

End Class

没有错误..没什么。我可以将图片从服务器发送到客户端,但不能反过来。还有一个奇怪的事情。我已将客户端的代码放在另一台机器上...当我像这样在 ep_client 中编写 ipv4(另一台机器的)时出现错误 Dim ep_client As New IPEndPoint(IPAddress.Parse("192.168.1.100"), 60000) .我没有错误。如果我像这样初始化服务器和客户端代码上的“udp-clients”:Dim client as new UdpClient(ep_client)它给出了一个错误:

Only one usage of each socket address (protocol/network address/port) is normally permitted



但是如果我这样写(在服务器端)Dim client as new UdpClient("127.0.0.1",60000)它没有错误。有什么区别?
哪里有问题?

最佳答案

您的直接问题是您在任何给定时间只能将一个套接字绑定(bind)到一台机器上的端口号 - 因此必须已经有一些东西绑定(bind)到端口 60000 才能为您提供“每个套接字地址只能使用一次......”异常- 也许您的程序的另一个实例已经在运行?

顺便说一句,我是一名游戏开发人员,并且了解使用 UDP 的必要性,这里用 UDP 代替 TCP 不是一个好的选择。 UDP 适用于小型“实时”数据而不是大型一次性数据。如果使用 UDP,您必须担心:可靠性 - 数据报可能根本无法通过,重复 - 数据报可能重复,拥塞控制 - 快速连续发送太多数据报而不检查先前的数据报是否通过只会导致它们被丢弃...真正发送大文件更适合TCP。

关于vb.net - 用于接收和发送的 udp 客户端不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36972456/

相关文章:

java - 像 JMeter 这样的程序可以测量 Java 套接字上每秒的事务数?

java - Android 将数据从主 UI 线程发送到另一个线程

qt - 将 QHash 序列化为 QByteArray

c++ - boost asio udp 套接字 async_receive_from 不调用处理程序

vb.net - 单击时隐藏按钮的边框

asp.net - 将事件监听器分配给 ASP.NET 中动态创建的 HTML 按钮

c - 伯克利套接字,运行简单的客户端和服务器连接

c# - 如何在父窗口最小化时防止子窗口最小化

asp.net - 为什么这个清晰可见的符号无法解析?

c++ - 异步 UDP 客户端/服务器通信 (BOOST) - 服务器不读取