How reconnect clients sockets to my server if my server restarts - vb.net

I'm trying to make a client-server connection using sockets.
It basically works pretty well; only one problem is when I close and re-open my server on server computer the clients won't reconnect
This is my client code :
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Public Class Form1
Public Delegate Sub MessageReceivedEventHandler(ByVal sender As Object, ByVal e As MessageReceivedEventArgs)
Public Delegate Sub ClientConnectedEventHandler(ByVal sender As Object, ByVal e As ClientConnectedEventArgs)
Public Event MessageReceived As MessageReceivedEventHandler
Public Event ClientConnected As ClientConnectedEventHandler
Public Buffer As Byte()
Public Shared Client As TcpClient
Dim Port As Integer = 5050
Dim host As String = "computer name"
Dim KEY As String = "mykey"
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim T As New Thread(AddressOf run)
T.Start()
End Sub
Private Sub run()
' Connect to the server'
Client = New TcpClient(host, Port)
Dim T As New Thread(AddressOf Receiver, 10)
T.Start()
End Sub
Public Shared Function StringToByte(ByVal STR As String) As Byte()
Return System.Text.Encoding.Default.GetBytes(STR)
End Function
Public Shared Function ByteToString(ByVal BYS As Byte()) As String
Return System.Text.Encoding.Default.GetString(BYS)
End Function
Public Sub Data(ByVal Sender As Object, ByVal Data As MessageReceivedEventArgs) Handles Me.MessageReceived
Dim info As Byte() = Data.Message
Dim Client As Socket = Data.clientSocket
Dim ID As String = Data.Sender
Dim Arr As String() = Split(System.Text.Encoding.Default.GetString(info), "mykey")
Try
Select Case Arr(0)
Case "MSG"
MsgBox(Arr(1))
End Select
Catch ex As Exception
MsgBox("Error Detected in Data Client :" & ex.Message)
End Try
End Sub
Sub Receiver()
Dim M As New MemoryStream
Try
If Client.Available > 0 Then
ReDim Buffer(Client.Available - 1)
Client.Client.Receive(Buffer, 0, Buffer.Length, SocketFlags.None)
M.Write(Buffer, 0, Buffer.Length)
If System.Text.Encoding.Default.GetString(M.ToArray).Contains("EOF") Then
Dim Data As Byte() = (M.ToArray).Remove(ConfigTcp.ENDOFPACKET)
Dim Msg As New MessageReceivedEventArgs
Msg.Message = Data
Msg.clientSocket = Client.Client
Msg.Sender = Client.Client.Handle.ToString()
RaiseEvent MessageReceived(Me, Msg)
M.Dispose()
M = New MemoryStream
End If
End If
Thread.Sleep(1)
Catch ex As Exception
MsgBox("Error Detected :" & ex.Message)
End Try
End Sub
Public Shared Sub Send(ByVal sock As Socket, ByVal s As String)
Send(sock, System.Text.Encoding.UTF8.GetBytes(s))
End Sub
Private Shared Sub Send(ByVal sock As Socket, ByVal b As Byte())
Try
Dim Memory As MemoryStream = New MemoryStream
Dim CB As Byte() = b
Memory.Write(CB, 0, CB.Length)
Memory.Write(ConfigTcp.ENDOFPACKET, 0, ConfigTcp.ENDOFPACKET.Length)
sock.Send(Memory.ToArray, 0, Memory.Length, SocketFlags.None)
Memory.Dispose()
Catch x As Exception
End Try
End Sub
End Class
Public Class MessageReceivedEventArgs
Inherits EventArgs
Public Sender As String
Public clientSocket As Socket
Public Message As Byte()
End Class
Public Class ClientConnectedEventArgs
Inherits EventArgs
Public clientID As String
Public clientSocket As Socket
End Class

Your client needs to handle disconnects and reconnect if needed.
To accomplish this, you can catch a SocketException and see why the socket was closed.
Depending on the exception you can run a method to have your client reconnect.
Public Sub DoReconnect()
Dim SecondsToWait as Integer=1
Do
Try
Client = New TcpClient(host, Port)
Exit Do
Catch SockEx as SocketException
'TODO: decide whether to attempt reconnection or exit
Catch Ex as Exception
'TODO: Most likely should terminate the program here
Console.WriteLine(Ex.ToString())
Exit Do
End Try
System.Threading.Thread.Sleep(SecondsToWait*1000)
SecondsToWait <<=1 ' Exponential Back Off Time
Loop
End Sub

#Alexander Higgins
I tried something like this but seems that SocketException happens only before opening the server for the first time.If I close the server it and re-open it, it doesn't catch SocketException
Public Sub DoReconnect()
re:
Thread.Sleep(1000)
Try
Client = New TcpClient(host, Port)
Dim T As New Thread(AddressOf Receiver, 10)
T.IsBackground = True
T.Start()
Catch SockEx As SocketException
MsgBox("SocketException " + SockEx.Message)
GoTo re
Catch Ex As Exception
MsgBox("Exception " + Ex.Message)
End Try
End Sub
Private Sub run()
DoReconnect()
End Sub

Related

Send and receive data from a websocket server using sockets in Vb.net

i am new to network programming and would really appreciate your help to receive and send data to a server. I am trying to Use Sockets to Send and Receive data from a server which is developed using WebSockets.
Until now i have created the following Code which i think is wrong: in this code i am trying to send data on a normal thread but receive data on a different thread so that the program dont go on hold.
as i send data to the server, after some time i get this text reply on the textbox in which i am trying to receive the server response:
HTTP/1.1 501 Not Implemented
Any help will be much appreciated
TCPControl class(handles the connection, send and receive matters)
Public Class TCPControl
Public client As TcpClient
Public DataStream As StreamWriter
Private ReceiveData As StreamReader
Private comThread As Thread
Public isListening As Boolean = True
Public Event MessageReceived(sender As TCPControl, Data As String)
Public Sub New(Host As String, Port As Integer)
Try
client = New TcpClient(Host, Port)
DataStream = New StreamWriter(client.GetStream)
comThread = New Thread(New ThreadStart(AddressOf Listening))
comThread.Start()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Listening()
Do Until isListening = False
If client.Connected = True Then
ReceiveData = New StreamReader(client.GetStream)
End If
Try
RaiseEvent MessageReceived(Me, ReceiveData.ReadLine)
Catch ex As Exception
End Try
Thread.Sleep(10)
Loop
End Sub
Public Sub Send(Data As String)
DataStream.Write(Data & vbCrLf)
DataStream.Flush()
End Sub End Class
Form1 class(handles form load and other stuff)
Public Class Form1
Private client As TCPControl
' Private receiveClient As TCPControlReceive
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' client = New TCPControl("174.129.224.73", 80)
client = New TCPControl(GetIpAddress("echo.websocket.org").ToString, 80)
If client.client.Connected Then Label1.Text = "Connected"
'receiveClient = New TCPControlReceive
AddHandler client.MessageReceived, AddressOf OnLineReceived
End Sub
Private Delegate Sub UpdateMessageDelegate(TB As TextBox, txt As String)
Private Sub UpdateText(TB As TextBox, txt As String)
If TB.InvokeRequired Then
TB.Invoke(New UpdateMessageDelegate(AddressOf UpdateText), New Object() {TB, txt})
Else
If txt IsNot Nothing Then
TB.AppendText(txt & vbCrLf)
End If
End If
End Sub
Private Sub OnLineReceived(sender As TCPControl, Data As String)
UpdateText(txtReceive, Data)
End Sub
Private Function GetIpAddress(address As String) As IPAddress
Dim ips As IPAddress()
ips = Dns.GetHostAddresses(address)
Return ips(0)
End Function
Private Sub SendMessage()
If client.client.Connected = True Then
client.Send(txtSend.Text)
End If
End Sub
Private Sub Form1_ContextMenuStripChanged(sender As Object, e As EventArgs) Handles Me.ContextMenuStripChanged
If client.client.Connected = True Then
client.DataStream.Close()
client.Client.Close()
End If
client.isListening = False
End Sub
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
SendMessage()
txtSend.Clear()
End Sub End Class
'HTTP/1.1 501 Not Implemented' was sent by the server, not generated by VB.
I would assume from this that your code works fine, and the problem lies with the command(s) you are sending after the client connects.

Sending an receiving two types of data across TCP connection

On the Client I want to -
I want to send a screenimage from the client and receive a string with cursor coordinates in.
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?

Tcp Client/Server - Client messages issue

I have client and server application.
I have the client disconnect from the server with client.close via a disconnect button.
I send a message, shows on server. ok works great.
I disconnect and then reconnect. I send a message. It shows the message two times.
I disconnect another time then reconnect. I send a message. It then shows the message three times.
It is incrementing the message and sending it multiple times after the disconnect and then reconnect.
Help? Been trying to figure this out for a while
[SERVER]
Public Class Server
Dim Listener As TcpListener
Dim Client As TcpClient
Dim ListenerThread As System.Threading.Thread
Dim ClientID As String
Dim ClientIP As String
Dim ClientIPandID As String
Dim ClientIPandPort As String
Dim TotalItemCount As String
Dim clientcount As Integer = 0
Private Sub Server_Load(sender As Object, e As EventArgs) Handles Me.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub ButtonStart_Click(sender As System.Object, e As System.EventArgs) Handles ButtonStart.Click
If TextBoxPort.Text = "" Then
MsgBox("Please Enter Port To Run On.")
Else
ListenerThread = New System.Threading.Thread(AddressOf Listening)
ListenerThread.IsBackground = True
ListenerThread.Start(TextBoxPort.Text)
ButtonStart.Enabled = False
ButtonStop.Enabled = True
ListBox1.Items.Add("[SERVER] Running on Port " + TextBoxPort.Text)
ListBox1.Items.Add("[SERVER] Waiting For A Connection...")
End If
End Sub
Private Sub Listening(ByVal Port As Integer)
Try
Listener = New TcpListener(IPAddress.Any, Port)
Listener.Start()
Do
Client = Listener.AcceptTcpClient 'Accepts Client Trying To Connect
If Client.Connected Then
MsgBox("Client Connected")
End If
clientcount += 1
GetClientInfo() 'Retrieves The Clients Info
AddHandler ReceivedMessage, AddressOf ReceivedMessage1
Loop Until False
Catch ex As Exception
End Try
End Sub
'Events
Public Event ReceivedMessage(ByVal Command As String)
Private Sub GenerateClientSessionNumber()
Dim r As New Random
Dim x As String = String.Empty
For i = 0 To 7
x &= Chr(r.Next(65, 89))
Next
ClientID = x
End Sub
Private Sub GetClientInfo()
GenerateClientSessionNumber()
ClientIPandID = Client.Client.RemoteEndPoint.ToString().Remove(Client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & ClientID
ClientIP = Client.Client.RemoteEndPoint.ToString().Remove(Client.Client.RemoteEndPoint.ToString().LastIndexOf(":"))
ClientIPandPort = Client.Client.RemoteEndPoint.ToString()
MsgBox(ClientIPandPort)
ListBox2.Items.Add(ClientIPandID)
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
End Sub
Private Sub ButtonStop_Click(sender As System.Object, e As System.EventArgs) Handles ButtonStop.Click
Listener.Stop()
Client.Close()
ButtonStop.Enabled = False
ButtonStart.Enabled = True
ListBox1.Items.Add("[SERVER] Server Stopped")
End Sub
Private Sub Reading()
Try
Dim Reader As New StreamReader(Client.GetStream)
Dim Command As String = Reader.ReadLine
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
RaiseEvent ReceivedMessage(command)
Catch ex As Exception
End Try
End Sub
Private Sub ReceivedMessage1(ByVal Command As String)
Dim Message() As String = Command.Split("|")
If Message(0) = "MESSAGE" Then
MsgBox("Message Received From Client " + ">" + Message(1))
End If
end sub
[CLIENT]
Public Class Client
Dim Client As New TcpClient
Sub Connect(ByVal ServerIP As String, ByVal Port As Integer)
'Try To Make Connection With Server
If Client.Connected = True Then
MsgBox("Already Connected")
MsgBox("Connected To " + Client.Client.RemoteEndPoint.ToString)
Else
MsgBox("Currently Not Connected. Trying To Connect...")
Try
Client.Connect(ServerIP, Port)
MsgBox("Connected")
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
Catch ex As Exception
MsgBox("Could Not Connect To Server. Check Server." + ex.Message.ToString)
End Try
End If
End Sub
Private Sub SendData(ByVal Message As String) 'Sends Data to Server
TextBox1.Text = Message
Try
If Client.Connected = True Then
Dim Writer As New StreamWriter(Client.GetStream)
Writer.WriteLine(Message)
Writer.Flush()
Else
MsgBox("Cannot Send Message. Connection To Server Is Not Active.")
End If
Catch ex As Exception
MsgBox("You Are Not Connected To The Server." + vbCrLf + ex.Message.ToString)
End Try
End Sub
Private Sub ButtonConnect_Click(sender As Object, e As EventArgs) Handles ButtonConnect.Click
Connect(TextBoxIPAddress.Text, TextBoxPort.Text)
End Sub
Private Sub ButtonSendMessage_Click(sender As Object, e As EventArgs) Handles ButtonSendMessage.Click
SendData("MESSAGE|" & TextBoxMessage.Text)
End Sub
Private Sub Client_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
SendData("DISCONNECT|")
Client.Close()
Client = New TcpClient
End Sub
End Class
i am not sure about the problem but i can give you some hypothesizes, firstly you add handler on every client you connect on server side and that means multiple pointer to the same place, secondly when you connect to server and reconnect you actually don't tell the server that the two clients are the same so he make two channels between the client and the server, the first is the old one that didn't close and he still have handler on it, the server don't recognize that the first is disconnected because he is connected! even if its another object at client. so when client disconnects , disconnect him from server too, or at every loop test if clients are connected before accepting do this test .
Since I have a class Called "ConnectedClient". I was able to make a call to that specific client or all clients and Close/Destroy the connection.

vb.net server - multiple clients continually processing different information

I am looking for help with writing a server application to serve an updating text stream to clients. My requirements are as follows:
I need to be able to have a client request information on server port 7878 and receive back an initial set of values, the changed values would then be reported every 5 seconds. The hanging point for me has been connecting another client. I need to be able to connect a 2nd (or 3rd or 4th) client while the first is still running. The second client would receive the initial values and then begin updating as well. I need the two streams to be completely independent of each other. Is this possible with VB.Net and TCP sockets?
Edit to add: I have pasted some of my code below of what I can share. WriteLog is a separate sub that isn't really relevant to my problem. This code will allow for a client to connect and then allow for another client to connect, but all transmissions to the 1st client stop on a new connection.
Public Class ServerApp
Dim serverSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim clientSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Private Sub ServerApp_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WriteLog(String.Format("Start of form load.."))
Dim listener As New Thread(New ThreadStart(AddressOf ListenForRequests))
listener.IsBackground = True
listener.Start()
End Sub
Private Sub ListenForRequests()
Dim CONNECT_QUEUE_LENGTH As Integer = 4
serverSocket.Bind(New IPEndPoint(IPAddress.Any, 7878))
serverSocket.Listen(CONNECT_QUEUE_LENGTH)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
End Sub
Private Sub OnAccept(ByVal ar As IAsyncResult)
clientSocket = serverSocket.EndAccept(ar)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
WriteLog("just accepted new client")
Try
clientSocket.Send(Encoding.UTF8.GetBytes("first response on connect"), SocketFlags.None)
While True
clientSocket.Send(Encoding.UTF8.GetBytes("string of updates"), SocketFlags.None)
Thread.Sleep(5000)
End While
Catch ex As Exception
WriteLog(ex.Message)
WriteLog("Remote host has disconnected")
End Try
End Sub
End Class
I recommend trying out the UdpClient class, i find it easier to use and understand.
Now for some code...
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.Net
Public Class Form1
Private port As Integer = 7878
Private Const broadcastAddress As String = "255.255.255.255"
Private receivingClient As UdpClient
Private sendingClient As UdpClient
Private myTextStream As String = "Blah blah blah"
Private busy As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
InitializeSender()
InitializeReceiver()
End Sub
Private Sub InitializeSender()
Try
sendingClient = New UdpClient(broadcastAddress, port)
sendingClient.EnableBroadcast = True
Catch ex As Exception
MsgBox("Error, unable to setup sender client on port " & port & "." & vbNewLine & vbNewLine & ex.ToString)
End Try
End Sub
Private Sub InitializeReceiver()
Try
receivingClient = New UdpClient(port)
ThreadPool.QueueUserWorkItem(AddressOf Receiver)
Catch ex As Exception
MsgBox("Error, unable to setup receiver on port " & port & "." & vbNewLine & vbNewLine & ex.ToString)
End
End Try
End Sub
Private Sub sendStream()
busy = True
Dim i% = 0
Do While i < 4
If myTextStream <> "" Then
Dim data() As Byte = Encoding.ASCII.GetBytes(myTextStream)
Try
sendingClient.Send(data, data.Length)
Catch ex As Exception
MsgBox("Error, unable to send stream." & vbNewLine & vbNewLine & ex.ToString)
End
End Try
End If
Thread.Sleep(5000)
i += 1
Loop
busy = False
End Sub
Private Sub Receiver()
Dim endPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, port)
While True
Dim data() As Byte
data = receivingClient.Receive(endPoint)
Dim incomingMessage As String = Encoding.ASCII.GetString(data)
If incomingMessage = "what ever the client is requesting, for example," & "GET_VALUES" Then
If busy = False Then Call sendStream()
End If
End While
End Sub
End Class
A few links that may help: Here,
here,
here and
here.

Chat system with one or two ways?

I'm trying con build a simple chat client/software (whole in on executable) wich start listen from the start on the port 5900 and when a client connect to that port the chat is established.
The problem is that only the client can chat to the server, the server cannot answer the client because the connection is working in one way.
The i've tried to connect from "server" to the client when it establishes a connection but the system crash warning me that the port is already on use.
This my code: (working in one way)
Imports System.Net.Sockets
Imports System.Text
Imports System.Reflection
Public Class frmComplete
Dim Data As Integer
Dim Message As String
Private sServer As TcpListener
Private sClient As New TcpClient
Private cServer As TcpListener
Private cClient As New TcpClient
Private cNick As String
Dim BufferSize(1024) As Byte
Private Delegate Sub MessageDelegate(ByVal Message As String)
Private Sub frmComplete_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
srvListen(5900)
btnSend.Enabled = False
End Sub
Private Sub OnServerConnect(ByVal AR As IAsyncResult)
sClient = sServer.EndAcceptTcpClient(AR)
sClient.GetStream.BeginRead(BufferSize, 0, BufferSize.Length, AddressOf OnRead, Nothing)
My.Computer.Audio.Play(Application.StartupPath & "\Connected.wav", AudioPlayMode.Background)
End Sub
Private Sub OnRead(ByVal AR As IAsyncResult)
Data = sClient.GetStream.EndRead(AR)
Message = Encoding.ASCII.GetString(BufferSize, 0, Data)
Dim Args As Object() = {Message}
Me.Invoke(New MessageDelegate(AddressOf PrintMessage), Args)
sClient.GetStream.BeginRead(BufferSize, 0, BufferSize.Length, AddressOf OnRead, Nothing)
End Sub
Private Sub PrintMessage(ByVal Message As String)
Try
txtChat.Text = txtChat.Text & Message & vbCrLf
My.Computer.Audio.Play(Application.StartupPath & "\Message.wav", AudioPlayMode.Background)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
Private Sub srvListen(ByVal port As Integer)
Try
sServer = New TcpListener(System.Net.IPAddress.Any, 5900)
sServer.Start()
'THIS WILL RAISE THE EVENT WHEN A CLIENT IS CONNECTED
sServer.BeginAcceptTcpClient(AddressOf OnServerConnect, Nothing)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub
Private Sub txtMessage_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtMessage.KeyDown
'FIXME (SOUND T_T)
If e.KeyCode = Keys.Enter Then
SendMessage(cNick & ":" & txtMessage.Text)
End If
End Sub
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
ConnectToServer(txtIP.Text)
cNick = txtNickname.Text
txtNickname.Enabled = False
txtIP.Enabled = False
btnConnect.Enabled = False
End Sub
Private Sub ConnectToServer(ByVal ipadress As String)
Try
cClient.BeginConnect(ipadress, 5900, AddressOf OnClientConnect, Nothing)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub OnClientConnect(ByVal AR As IAsyncResult)
Try
cClient.EndConnect(AR)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Not String.IsNullOrEmpty(txtMessage.Text) Then
txtChat.Text = txtChat.Text & "Me:" & txtMessage.Text & vbCrLf
SendMessage(cNick & ":" & txtMessage.Text)
End If
End Sub
Private Sub SendMessage(ByVal message As String)
If cClient.Connected = True Then
Dim Writer As New IO.StreamWriter(cClient.GetStream)
Writer.Write(message)
Writer.Flush()
End If
txtMessage.Text = ""
End Sub
Private Sub SendCommand(ByVal command As String)
If cClient.Connected = True Then
Dim Writer As New IO.StreamWriter(cClient.GetStream)
Writer.Write(command)
Writer.Flush()
End If
txtMessage.Text = ""
End Sub
Private Sub txtMessage_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMessage.TextChanged
If Not String.IsNullOrEmpty(txtMessage.Text) Then
btnSend.Enabled = True
Else
btnSend.Enabled = False
End If
End Sub
End Class
What I should do? use two ports? one for write and another to read? And if i need to conect multiple clients to one user? (remember the same exe is server/client)
Please help me =(
You aren't reading any data coming back from the Server. You'll notice in your OnServerConnect method you call the BeginRead -- you will also need to do this for your client in the OnClientConnect method, or you'll get a one way communication. Perhaps this is why you are not seeing any data coming through?
I'm guessing, when your Server sends back the data to the client, you aren't getting a hard-error, just no data.
Just glancing over your code I noticed that you have both a TcpClient and TcpListener for your client and server. You don't need this. Your SERVER will be the TcpListener, and your CLIENT will be the TcpClient. By asking if you should connect back on a different port from the server, you are shortchanging yourself of what the TCP connection really is. Once your TcpClient has connected to the TcpServer, your connection is established. There is no need further to attempt to connect.
You're client code should be something similar to:
Private Sub OnClientConnect(ByVal AR As IAsyncResult)
Try
cClient.EndConnect(AR)
sServer.GetStream.BeginRead(BufferSize, 0, BufferSize.Length, AddressOf OnClientRead, Nothing)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub OnClientRead(ByVal AR As IAsyncResult)
Data = sServer.GetStream.EndRead(AR)
Message = Encoding.ASCII.GetString(BufferSize, 0, Data)
Dim Args As Object() = {Message}
Me.Invoke(New MessageDelegate(AddressOf PrintMessage), Args)
sServer.GetStream.BeginRead(BufferSize, 0, BufferSize.Length, AddressOf OnClientRead, Nothing)
End Sub