1

On the Client I want to -

  1. I want to send a screenimage from the client and receive a string with cursor coordinates in.
  2. On the server I want to receive and display the screenimage on Form2 and then send back my cursor coordinates to the client.

I can successfully send text messages from the client and receive them on the server using this code -

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        senddata("CHAT|" & TextBox3.Text) 'send the data with CHAT| as header
        TextBox4.Text &= "You: " & " " & TextBox3.Text.Split("|")(0) & vbNewLine
End Sub

Sub senddata(ByVal message As String)
   Dim sw As New StreamWriter(t.GetStream) 'declare a new streamwriter
   sw.WriteLine(message) 'write the message
   sw.Flush()
End Sub

and receive it on the server with this code -

Imports System.IO
Imports System.Net.Sockets
Public Class ConnectedClient
    Private cli As TcpClient 'decleare a tcp client which will be the client that we assign to an instance of this class
    Private uniqueid As String 'this will be used for the name property
    Public Property name ''This will be the name of the ID containing its Unique ID 
        Get
            Return uniqueid 'when we want to get it, it will return the Unique ID 
        End Get
        Set(ByVal value)
            uniqueid = value 'Used for setting the name
        End Set
    End Property
    Sub New(ByVal client As TcpClient)

        Dim r As New Random 'create a new random to serve as way to create our unique ID
        Dim x As String = String.Empty 'declare a new variable to hold the ID
        For i = 0 To 7 'we are goign to have an ID of 7 randomly generated characters
            x &= Chr(r.Next(65, 89)) 'create a generate dnumber between 65 and 89 and get the letter that has the same ascii value (A-Z)
            '                         and add it onto the ID string
        Next
        Me.name = client.Client.RemoteEndPoint.ToString().Remove(client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & x 'set the name to the Unique ID 
        cli = client 'assign the client specified to the TCP client variable to we can operate with it
        cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'start reading using the read subroutine

    End Sub
    Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient)    'this is raised when we get a message from the client
    Public Event disconnected(ByVal client As ConnectedClient)    'this is raised when we get the client disconnects
    Sub read(ByVal ar As IAsyncResult) 'this will process all messages being recieved
        Try
            Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
            Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
            RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
            '                               the current client which it has recieved the message from to perform any client specific
            '                               tasks if needed
            cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
        Catch ex As Exception
            Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
                Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
                Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
                RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
                '                               the current client which it has recieved the message from to perform any client specific
                '                               tasks if needed
                cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
            Catch ' IF WE STILL CANNOT READ
                RaiseEvent disconnected(Me)  'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
            End Try

        End Try
    End Sub
    Sub senddata(ByVal message As String) 'this is used to deal with sending out messages
        Dim sw As New StreamWriter(cli.GetStream) 'declare a new streamwrite to write to the stream between the client and the server
        sw.WriteLine(message) 'write the message to the stream
        sw.Flush()
    End Sub

    Sub listen(ByVal port As Integer)
    Try
        Dim t As New TcpListener(IPAddress.Any, port) 'declare a new tcplistener
        t.Start() 'start the listener
        Do

            Dim client As New ConnectedClient(t.AcceptTcpClient) 'initialize a new connected client
            AddHandler client.gotmessage, AddressOf recieved 'add the handler which will raise an event when a message is recieved
            AddHandler client.disconnected, AddressOf disconnected 'add the handler which will raise an event when the client disconnects

        Loop Until False
    Catch
    End Try

End Sub

In a totally different application I can successfully send the screen image from the client using this code

    Imports System.Net.Sockets
Imports System.Threading
Imports System.Drawing
Imports System.Runtime.Serialization.Formatters.Binary
Public Class Form1
    Dim client As New TcpClient
    Dim ns As NetworkStream
    Dim port As Integer
    Dim server As TcpListener
    Dim listening As New Thread(AddressOf Listen)
    Dim GetImage As New Thread(AddressOf ReceiveCursor)

    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles btnConnect.Click
        port = CInt(txtPort.Text)
        Try
            If btnConnect.Text = "Connect" Then
                client.Connect(txtIP.Text, port)
                'MsgBox("Client connected !")
                Timer1.Start()
                btnConnect.Text = "Disconnect"
            Else
                btnConnect.Text = "Connect"
                Timer1.Stop()

            End If

        Catch ex As Exception
            MsgBox("Failed to connect..." + ex.Message)
        End Try
    End Sub

    Public Function Desktop() As Image
        Dim bounds As Rectangle = Nothing
        Dim screenshot As System.Drawing.Bitmap = Nothing
        Dim graph As Graphics = Nothing
        bounds = Screen.PrimaryScreen.Bounds
        screenshot = New Bitmap(bounds.Width, bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        graph = Graphics.FromImage(screenshot)
        graph.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy)
        Return screenshot
    End Function

    Private Sub SendDesktop()
        Dim bf As New BinaryFormatter
        ns = client.GetStream
        bf.Serialize(ns, Desktop())
    End Sub



    Private Sub BtnShare_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShare.Click
        If btnShare.Text.StartsWith("Share") Then
            Timer1.Start()
            'port = Integer.Parse(Me.txtPort.Text)
            'server = New TcpListener(port)
            'listening.Start()
            btnShare.Text = "Stop Sharing"
        Else
            Timer1.Stop()
            btnShare.Text = "Share Desktop"
        End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        SendDesktop()
        ' SetCursorPosition()
    End Sub

    Private Sub ReceiveCursor()
        Dim bf As New BinaryFormatter
        While client.Connected = True
            ns = client.GetStream
            txtCursorPosition.Text = bf.Deserialize(ns)
        End While
    End Sub

    Private Sub Listen()
        While client.Connected = False
            server.Start()
            client = server.AcceptTcpClient
        End While
        GetImage.Start()
    End Sub

    Public Sub StopListening()
        GetImage.Abort()
        server.Stop()
        client = Nothing
        If listening.IsAlive Then
            listening.Abort()
        End If

    End Sub

End Class

and receive it on the server using this code -

Imports System.Net.Sockets
Imports System.Threading
Imports System.Drawing
Imports System.Runtime.Serialization.Formatters.Binary

Public Class Form2
    Dim port As Integer
    Dim client As New TcpClient
    Dim ns As NetworkStream
    Dim server As TcpListener
    Dim listening As New Thread(AddressOf Listen)
    Dim GetImage As New Thread(AddressOf ReceiveImage)

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Start the timer, obtain the port and start listening
        Timer1.Start()
        port = Integer.Parse(Form1.txtPort.Text)
        server = New TcpListener(port)
        listening.Start()

    End Sub

    Private Sub ReceiveImage()
        Dim bf As New BinaryFormatter
        While client.Connected = True
            ns = client.GetStream
            PictureBox1.Image = bf.Deserialize(ns)
        End While
    End Sub

    Private Sub Listen()
        While client.Connected = False
            server.Start()
            client = server.AcceptTcpClient
        End While
        GetImage.Start()
    End Sub

    Public Sub StopListening()
        GetImage.Abort()
        server.Stop()
        client = Nothing
        If listening.IsAlive Then
            listening.Abort()
        End If

    End Sub

   End Class

Is there a way of doing both using the same connection and somehow detecting which is text and which is the screenimage?

  • 1
    You need to implement message framing, and only manage raw byte data. Possible duplicate of [TCP Client to Server communication](http://stackoverflow.com/questions/35233852/tcp-client-to-server-communication) – Visual Vincent Apr 05 '17 at 13:13
  • The answer above uses text [messages] as an example, but the code operates on byte arrays so you just need to manage the received packet differently. – Visual Vincent Apr 05 '17 at 13:34
  • Thanks Vincent, I have one application that sends and receives the screen OK and another application which sends and receives text messages OK. The problem is I cannot work out a way to do both on the same connection. Somehow I need to detect whether the message is a text string or a serialized image and the deal with each one accordingly. – user1997350 Apr 06 '17 at 09:13
  • I know that, you said so in the question. I just told you what you need to do and gave you a link. Message framing is to detect the start/end of data _and_ the data type. [**Here's another answer**](http://stackoverflow.com/questions/37341382/c-sharp-deserializing-a-struct-after-receiving-it-through-tcp/37352525#37352525) of mine explaining the concept. – Visual Vincent Apr 06 '17 at 11:34

0 Answers0