Udp客户端用于接收和发送不工作

时间:2016-05-01 22:00:08

标签: vb.net sockets udp

我成功创建了一个UDP客户端 - 服务器连接并在其上发送了一个大图像。我分割并将图像发送到每个1500字节的数据包。我在另一端获得330025字节的353723(我认为很不错)。但是你知道UDP数据包不是正常的,所以我必须对它发送的每个数据包进行id(我不能使用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中写这个Dim ep_client As New IPEndPoint(IPAddress.Parse("192.168.1.100"), 60000)的ipv4(其他机器)的ipv4时会出错。
我没有错误。如果我在服务器和客户端代码上初始化两个'udp-clients',如下所示:Dim client as new UdpClient(ep_client)它会出错:

  

每个套接字地址只有一种用法(协议/网络地址/端口)   通常是允许的

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

1 个答案:

答案 0 :(得分:1)

您当前的问题是,在任何给定时间您只能将一个Socket绑定到一台计算机上的端口号 - 因此必须已经绑定到端口60000的某些内容才能为您提供“每个套接字地址只有一次使用”。 “例外 - 你的程序的另一个实例可能已经在运行了吗?

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