sergiu reznicencu
sergiu reznicencu

Reputation: 1039

Udp client used for receiving and sendin not working

     I succeded creating a UDP client-server connection and sending a large image over it.
     I split and sent the image into packets of 1500 bytes each .I got at the other end 330025 bytes of 353723 (which I think is pretty good). But as you know UDP packets are not in order so I have to id every packet it's sent (I can't use tcp because I need speed for my project-game). Now I want to ask the 'server' for the missing packets.



This is the server's code:

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

This is the code for the client(which becomes a server...):

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


     No error..nothing. I can send a picture from server to client but not the other way around. And there's another weird thing. I've put the client's code on another machine...It's gives an error when I write the ipv4(of the other machine) in ep_client like this Dim ep_client As New IPEndPoint(IPAddress.Parse("192.168.1.100"), 60000).
     I get no error. And if I initialize both of the 'udp-clients' on server and client code like this : Dim client as new UdpClient(ep_client) it gives an error :

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

But if I write it like this (on the server side) Dim client as new UdpClient("127.0.0.1",60000) it gives no error.What's the difference? Where is the problem?

Upvotes: 1

Views: 1671

Answers (1)

markmnl
markmnl

Reputation: 11426

Your immediate problem is you can only have one Socket bound to a port number on one machine at any given time - so there must already be something bound to port 60000 to give you the "Only one usage of each socket address..." Exception - perhaps another instance of your program is already running?

Aside, and I am a game developer and understand the need to use UDP, UDP is not a good choice here instead of TCP. UDP is good for small "real-time" data not large one-off data. If using UDP you have to worry about: reliability - the datagram may not get through at all, duplicates - the datagram may be duplicate, congestion control - sending too many datagrams in quick succession without checking previous ones are getting through will just result in them being dropped... Really sending a large file is much better suited to TCP.

Upvotes: 1

Related Questions