Simultaneously receive message from clients using sockets (with Async) - vb.net

i have a CyberCafe Software Program with a code that sends a message by the client(socket) and received by the server(also a socket) using Network Stream. (i'm somewhat new about sockets and network stream)
Server Side:
'receive msg from client
Private Sub OnRecieve(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
ns.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf OnRecieve), ns)
Dim bytesRec As Byte() = byteData
Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec)
Invoke(New _Read(AddressOf Read), message)
ns.Flush()
ns.Close()
Catch ex As Exception
'check for Disconnection or Force Disconnection
Invoke(New _dc(AddressOf dc))
End Try
End Sub
Client Side:
'send msg to server
Private Sub Send(ByVal msg As String, ByVal client As Socket)
Try
Dim sendBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(msg)
NetStream = New NetworkStream(client)
NetStream.BeginWrite(sendBytes, 0, sendBytes.Length, New AsyncCallback(AddressOf OnSend), NetStream)
Catch ex As Exception
If Not clientSocket.Connected Then 'if connection was forcibly disconnected
'reconnecting to the server
Invoke(New _status(AddressOf status), clientSocket)
Connect()
End If
End Try
End Sub
The scenario is, there are 2 clients waiting to connect to the server(the other one is a Virtual Machine), and when i finally run the server, simultaneous connection had no problems, but receiving a message simultaneously didn't worked out. Sometimes it received one message only. Sometimes the message is wrong. Maybe a deadlock.
So, how can i implement this kind of situation? i asked Brother Google :P and he told me about AsyncTask, but i dunno how to do it :(
Any help would be obliged ^_^ Apologies for any bad english.

Update:
Sorry for my incomplete question.
I've added the EndRead/EndWrite method, but i'm not sure if i used the EndRead method right... I just inserted the EndRead before the BeginRead, but it still works though.
Thank you for the help Visual Vincent ^_^.
Also, my sockets are stored in the ListView as tag after they connect. And their IPAddress and HostName are stored in the database (MSAccess). And i don't have any TCP used in this code. Just Sockets and NetworkStreams. IDK if that is ok, but it works.
Server Side(Full):
Imports System.Net, System.Net.Sockets
Imports System.Data.OleDb
Public Class Server
Dim serverSocket As Socket
Dim clientSocket As Socket
Dim netstream As NetworkStream
Dim byteData(1023) As Byte
Dim ipEndPoint As IPEndPoint
Dim myList As New List(Of String)
Dim myList2 As New List(Of String)
Dim txt As String
'listening to clients from port 8800
Private Sub frmServer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Invoke(New _AddExistingClient(AddressOf AddExistingClient))
Listen()
End Sub
Delegate Sub _AddExistingClient()
Private Sub AddExistingClient()
Try
If conn.State = ConnectionState.Open Then conn.Close()
conn.Open()
query = "select * from Clients_tbl"
comm = New OleDbCommand(query, conn)
reader = comm.ExecuteReader
While reader.Read
Dim lvi As New ListViewItem(reader("HostName").ToString)
lvi.Text = reader("HostName")
lvi.SubItems.Add("P00.00") 'price 1
lvi.SubItems.Add("00:00:00") 'time 2
lvi.ImageKey = "Grey.ico"
lsvClients.Items.Add(lvi)
End While
lsvClients.Sort()
conn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Listen()
Try
serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
ipEndPoint = New IPEndPoint(IPAddress.Any, 8800)
serverSocket.Bind(ipEndPoint)
serverSocket.Listen(1)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OnAccept(ByVal ar As IAsyncResult)
Try
clientSocket = serverSocket.EndAccept(ar)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
CheckIfExist(clientSocket)
netstream = New NetworkStream(clientSocket)
netstream.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf OnRecieve), netstream)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _CheckIfExist(ByVal client As Socket)
Private Sub CheckIfExist(ByVal client As Socket)
Try
If InvokeRequired Then
Invoke(New _CheckIfExist(AddressOf CheckIfExist), client)
Exit Sub
End If
Dim RemoteIP As String = IPAddress.Parse(CType(client.RemoteEndPoint, IPEndPoint).Address.ToString).ToString
Dim host As String = Dns.GetHostEntry(RemoteIP).HostName.ToString
If conn.State = ConnectionState.Open Then conn.Close()
conn.Open()
query = "select * from Clients_tbl where HostName = '" + host + "'"
comm = New OleDbCommand(query, conn)
reader = comm.ExecuteReader
While reader.Read
If reader("IPAddress").ToString <> RemoteIP Then 'if socket do exist in the database but IPAddress was changed
ChangeIP(RemoteIP, host)
End If
count += 1
End While
If count = 0 Then 'if socket do not exist in the database
Add2DB(RemoteIP, host)
AddNewClient(client)
ElseIf count = 1 Then 'if socket do exist in the database and in the listview
For Each item As ListViewItem In lsvClients.Items
If item.Text = host Then
item.Tag = client
item.ImageKey = "Red.ico"
End If
Next
ElseIf count > 1 Then
MsgBox("Duplicate found")
End If
count = 0
conn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _ChangeIP(ByVal RemoteIP As String, ByVal host As String)
Private Sub ChangeIP(ByVal RemoteIP As String, ByVal host As String) 'connection is still opened
Try
If InvokeRequired Then
Invoke(New _ChangeIP(AddressOf ChangeIP), RemoteIP, host)
Exit Sub
End If
query = "update Clients_tbl set IPAddress = '" + RemoteIP + "' where HostName = '" + host + "'"
comm = New OleDbCommand(query, conn)
reader = comm.ExecuteReader
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _Add2DB(ByVal RemoteIP As String, ByVal host As String)
Private Sub Add2DB(ByVal RemoteIP As String, ByVal host As String) 'connection is still opened
Try
If InvokeRequired Then
Invoke(New _Add2DB(AddressOf Add2DB), RemoteIP, host)
Exit Sub
End If
query = "insert into Clients_tbl values('" + RemoteIP + "', '" + host + "')"
comm = New OleDbCommand(query, conn)
reader = comm.ExecuteReader
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'add client to ListView
Delegate Sub _AddNewClient(ByVal client As Socket)
Private Sub AddNewClient(ByVal client As Socket)
Try
If InvokeRequired Then
Invoke(New _AddNewClient(AddressOf AddNewClient), client)
Exit Sub
End If
Dim lvi As New ListViewItem(client.LocalEndPoint.ToString)
Dim RemoteIP As String = IPAddress.Parse(CType(client.RemoteEndPoint, IPEndPoint).Address.ToString).ToString
Dim host As String = Dns.GetHostEntry(RemoteIP).HostName.ToString
lvi.Text = host
lvi.Tag = client
lvi.SubItems.Add("P00.00") 'price 1
lvi.SubItems.Add("00:00:00") 'time 2
lvi.ImageKey = "Red.ico"
lsvClients.Items.Add(lvi)
lsvClients.Sort()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'Send msg to specific client
Private Sub Send(ByVal msg As String, ByVal client As Socket)
Try
netstream = New NetworkStream(client)
Dim sendBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(msg)
netstream.BeginWrite(sendBytes, 0, sendBytes.Length, New AsyncCallback(AddressOf OnSend), netstream)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OnSend(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
ns.EndWrite(ar)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _dc()
Private Sub dc()
For Each lvi As ListViewItem In lsvClients.Items
If Not lvi.Tag Is Nothing Then
Dim S As Socket = lvi.Tag
If Not S.Connected Then lvi.ImageKey = "Grey.ico"
End If
Next
End Sub
'receive msg from client
Private Sub OnRecieve(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
ns.EndRead(ar)
ns.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf OnRecieve), ns)
Dim bytesRec As Byte() = byteData
Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec)
Invoke(New _Read(AddressOf Read), message)
ns.Flush()
ns.Close()
Catch ex As Exception
'check for Disconnection or Force Disconnection
Invoke(New _dc(AddressOf dc))
End Try
End Sub
Delegate Sub _Read(ByVal msg As String)
Private Sub Read(ByVal msg As String)
Try
myList2 = msg.Split("~").ToList
'mylist.Add("0") 'command number
'mylist.Add(host) 'host name of this client
'mylist.Add(lblState.Text)
'mylist.Add(lblTime.Tag.ToString)
Select Case Integer.Parse(myList2(0))
Case 0
For Each lvi As ListViewItem In lsvClients.Items
If lvi.Text = myList2(1) Then
If myList2(2) = "Timed" Then
lvi.ImageKey = "Green.ico"
ElseIf myList2(2) = "Open"
lvi.ImageKey = "Blue.ico"
End If
lvi.SubItems(2).Tag = Integer.Parse(myList2(3))
End If
Next
End Select
myList2.Clear()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
Invoke(New _Counter(AddressOf Counter))
End Sub
Delegate Sub _Counter()
Private Sub Counter()
Try
If lsvClients.Items.Count > 0 Then
For Each time As ListViewItem In lsvClients.Items
'//////////////
If time.ImageKey = "Green.ico" Then
time.SubItems(2).Tag -= 1
time.SubItems(2).Text = GetTime(time.SubItems(2).Tag)
If time.SubItems(2).Tag = 0 Then time.ImageKey = "Red.ico"
ElseIf time.ImageKey = "Blue.ico" Then
time.SubItems(2).Tag += 1
time.SubItems(2).Text = GetTime(time.SubItems(2).Tag)
End If
'//////////////
Next
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Function GetTime(ByVal time As Integer) As String
Dim Hrs As Integer 'number of hours '
Dim Min As Integer 'number of Minutes '
Dim Sec As Integer 'number of Sec '
'Seconds'
Sec = time Mod 60
'Minutes'
Min = ((time - Sec) / 60) Mod 60
'Hours'
Hrs = ((time - (Sec + (Min * 60))) / 3600) Mod 60
Return Format(Hrs, "00") & ":" & Format(Min, "00") & ":" & Format(Sec, "00")
End Function
Private Sub btnStartTime_Click(sender As Object, e As EventArgs) Handles btnStartTime.Click
Try
If lsvClients.SelectedItems.Count <> 0 Then
myList.Add("0")
myList.Add("10") 'time
myList.Add("15") 'price
txt = String.Join("~", myList)
Send(txt, lsvClients.SelectedItems(0).Tag)
lsvClients.SelectedItems(0).SubItems(2).Tag = myList(1)
lsvClients.SelectedItems(0).ImageKey = "Green.ico"
myList.Clear()
Else
MsgBox("Select first")
End If
Catch ex As Exception
Dim client As Socket = lsvClients.SelectedItems(0).Tag
If Not client.Connected Then
MsgBox("Disconnected")
End If
End Try
End Sub
Private Sub btnOpenTime_Click(sender As Object, e As EventArgs) Handles btnOpenTime.Click
Try
If lsvClients.SelectedItems.Count <> 0 Then
myList.Add("2")
myList.Add("0") 'time
myList.Add("0") 'price
txt = String.Join("~", myList)
Send(txt, lsvClients.SelectedItems(0).Tag)
lsvClients.SelectedItems(0).SubItems(2).Tag = myList(1)
lsvClients.SelectedItems(0).ImageKey = "Blue.ico"
myList.Clear()
Else
MsgBox("Select first")
End If
Catch ex As Exception
Dim client As Socket = lsvClients.SelectedItems(0).Tag
If Not client.Connected Then
MsgBox("Disconnected")
End If
End Try
End Sub
Private Sub btnExtendTime_Click(sender As Object, e As EventArgs) Handles btnExtendTime.Click
Try
If lsvClients.SelectedItems.Count <> 0 Then
myList.Add("1")
myList.Add("10") 'time
myList.Add("15") 'price
txt = String.Join("~", myList)
Send(txt, lsvClients.SelectedItems(0).Tag)
lsvClients.SelectedItems(0).SubItems(2).Tag += myList(1)
lsvClients.SelectedItems(0).ImageKey = "Green.ico"
myList.Clear()
Else
MsgBox("Select first")
End If
Catch ex As Exception
Dim client As Socket = lsvClients.SelectedItems(0).Tag
If Not client.Connected Then
MsgBox("Disconnected")
End If
End Try
End Sub
Private Sub btnPauseTime_Click(sender As Object, e As EventArgs) Handles btnPauseTime.Click
Try
If lsvClients.SelectedItems.Count <> 0 Then
myList.Add("3")
myList.Add("00:00:00") 'time
myList.Add("0") 'price
txt = String.Join("~", myList)
Send(txt, lsvClients.SelectedItems(0).Tag)
If lsvClients.SelectedItems(0).ImageKey = "Green.ico" Then
lsvClients.SelectedItems(0).ImageKey = "Green2Yellow.ico"
ElseIf lsvClients.SelectedItems(0).ImageKey = "Blue.ico"
lsvClients.SelectedItems(0).ImageKey = "Blue2Yellow.ico"
End If
myList.Clear()
Else
MsgBox("Select first")
End If
Catch ex As Exception
Dim client As Socket = lsvClients.SelectedItems(0).Tag
If Not client.Connected Then
MsgBox("Disconnected")
End If
End Try
End Sub
Private Sub btnResumeTime_Click(sender As Object, e As EventArgs) Handles btnResumeTime.Click
Try
If lsvClients.SelectedItems.Count <> 0 Then
myList.Add("4")
myList.Add("00:00:00") 'time
myList.Add("0") 'price
txt = String.Join("~", myList)
Send(txt, lsvClients.SelectedItems(0).Tag)
If lsvClients.SelectedItems(0).ImageKey = "Green2Yellow.ico" Then
lsvClients.SelectedItems(0).ImageKey = "Green.ico"
ElseIf lsvClients.SelectedItems(0).ImageKey = "Blue2Yellow.ico"
lsvClients.SelectedItems(0).ImageKey = "Blue.ico"
End If
myList.Clear()
Else
MsgBox("Select first")
End If
Catch ex As Exception
Dim client As Socket = lsvClients.SelectedItems(0).Tag
If Not client.Connected Then
MsgBox("Disconnected")
End If
End Try
End Sub
End Class
Client Side(full):
Imports System.Net, System.Net.Sockets, System.IO
Public Class Client
Dim clientSocket As Socket
Dim NetStream As NetworkStream
Dim byteData(1023) As Byte
Dim ipEndpoint As IPEndPoint
Dim host As String = Dns.GetHostName
Dim ip As IPAddress = IPAddress.Parse("192.168.56.1") 'Dns.GetHostEntry(host).AddressList(0)
Dim AppPath As String = Application.StartupPath
Dim writer As StreamWriter
Dim reader As StreamReader
Dim mylist As New List(Of String)
Dim txt As String
'/////////////////////connecting to server at port 8800
Private Sub Client_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Try
Invoke(New _readtext(AddressOf readtext))
Connect()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Connect()
Try
clientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
ipEndpoint = New IPEndPoint(ip, 8800)
clientSocket.BeginConnect(ipEndpoint, New AsyncCallback(AddressOf OnConnect), Nothing)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OnConnect(ByVal ar As IAsyncResult)
Try
Invoke(New _status(AddressOf status), clientSocket)
clientSocket.EndConnect(ar)
'Invoke(New _SendTimeState(AddressOf SendTimeState))
NetStream = New NetworkStream(clientSocket)
NetStream.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf Recieve), NetStream)
'Invoke(New _SendTimeState(AddressOf SendTimeState))
Catch ex As Exception
If Not clientSocket.Connected Then
Invoke(New _status(AddressOf status), clientSocket)
Connect()
End If
End Try
End Sub
Delegate Sub _SendTimeState()
Private Sub SendTimeState()
Try
mylist.Add("0") 'command number
mylist.Add(host) 'host name of this client
mylist.Add(lblState.Text)
mylist.Add(lblTime.Tag.ToString)
txt = String.Join("~", mylist)
Send(txt, clientSocket)
txt = ""
mylist.Clear()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _readtext()
Private Sub readtext()
Try
reader = New StreamReader(AppPath & "\time.txt")
Dim x As Integer = reader.ReadLine
reader.Close()
If x <> 0 Then
lblTime.Tag = x
reader = New StreamReader(AppPath & "\state.txt")
Dim state As String = reader.ReadLine
reader.Close()
lblState.Text = state
Timer1.Start()
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _writetext(ByVal file As String, ByVal txt As String)
Private Sub writetext(ByVal file As String, ByVal txt As String)
Try
If InvokeRequired Then
Invoke(New _writetext(AddressOf writetext), file, txt)
Exit Sub
End If
writer = New StreamWriter(AppPath & file, False)
writer.WriteLine(txt)
writer.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Delegate Sub _status(ByVal client As Socket)
Private Sub status(ByVal client As Socket)
lblConnection.Text = client.Connected.ToString
End Sub
'receive msg from server
Private Sub Recieve(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
ns.EndRead(ar)
ns.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf Recieve), ns)
Dim bytesRec As Byte() = byteData
Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec)
Invoke(New _Read(AddressOf Read), message)
Catch ex As Exception
If Not clientSocket.Connected Then 'if connection was forcibly disconnected
'reconnecting to the server
Invoke(New _status(AddressOf status), clientSocket)
Connect()
End If
End Try
End Sub
Delegate Sub _Read(ByVal msg As String)
Private Sub Read(ByVal msg As String)
Try
mylist = msg.Split("~").ToList
'mylist(0) is command
'mylist(1) is time
'mylist(2) price
Select Case Integer.Parse(mylist(0))
Case 0 'timed
lblState.Text = "Timed"
lblTime.Tag = Integer.Parse(mylist(1))
lblTime.Text = GetTime(lblTime.Tag)
lblPrice.Text = Integer.Parse(lblPrice.Text) + Integer.Parse(mylist(2))
lblState.Tag = lblState.Text
writetext("\time.txt", lblTime.Tag.ToString)
writetext("\state.txt", "Timed")
Timer1.Start()
Case 1 'extend time
lblTime.Tag += Integer.Parse(mylist(1))
lblTime.Text = GetTime(lblTime.Tag)
lblPrice.Text = Integer.Parse(lblPrice.Text) + Integer.Parse(mylist(2))
If Not Timer1.Enabled Then Timer1.Start()
Case 2 'open time
lblState.Text = "Open"
lblTime.Tag = Integer.Parse(mylist(1))
lblTime.Text = GetTime(lblTime.Tag)
lblPrice.Text = mylist(2)
lblState.Tag = lblState.Text
writetext("\time.txt", lblTime.Tag.ToString)
writetext("\state.txt", "Open")
Timer1.Start()
Case 3 'pause time
lblState.Text = "Paused"
Timer1.Stop()
Case 4 'resume time
lblState.Text = lblState.Tag
Timer1.Start()
Case 5 'stop time
lblState.Text = "Stop"
writetext("\time.txt", "0")
writetext("\state.txt", "Stop")
Timer1.Stop()
Case 6 'shutdown
Case 7 'reset
Case 8 'send msg
End Select
mylist.Clear()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
'send msg to server
Private Sub Send(ByVal msg As String, ByVal client As Socket)
Try
Dim sendBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(msg)
NetStream = New NetworkStream(client)
NetStream.BeginWrite(sendBytes, 0, sendBytes.Length, New AsyncCallback(AddressOf OnSend), NetStream)
Catch ex As Exception
If Not clientSocket.Connected Then 'if connection was forcibly disconnected
'reconnecting to the server
Invoke(New _status(AddressOf status), clientSocket)
Connect()
End If
End Try
End Sub
Private Sub OnSend(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
ns.EndWrite(ar)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
Try
Select Case lblState.Text
Case "Timed"
lblTime.Tag -= 1
lblTime.Text = GetTime(lblTime.Tag)
writetext("\time.txt", lblTime.Tag.ToString)
If lblTime.Tag = 0 Then Timer1.Stop()
Case "Open"
lblTime.Tag += 1
lblTime.Text = GetTime(lblTime.Tag)
writetext("\time.txt", lblTime.Tag.ToString)
End Select
Catch ex As Exception
If Not clientSocket.Connected Then 'if connection was forcibly disconnected
'reconnecting to the server
Invoke(New _status(AddressOf status), clientSocket)
Connect()
End If
MsgBox(ex.ToString)
End Try
End Sub
Private Function GetTime(ByVal time As Integer) As String
Dim Hrs As Integer 'number of hours '
Dim Min As Integer 'number of Minutes '
Dim Sec As Integer 'number of Sec '
'Seconds'
Sec = time Mod 60
'Minutes'
Min = ((time - Sec) / 60) Mod 60
'Hours'
Hrs = ((time - (Sec + (Min * 60))) / 3600) Mod 60
Return Format(Hrs, "00") & ":" & Format(Min, "00") & ":" & Format(Sec, "00")
End Function
End Class
OleDb Module:
Imports System.Data.OleDb
Module oledb
Dim AppPath As String = Application.StartupPath
Public conn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + AppPath + "\ServerDatabase.mdb;User Id=Admin;Password=")
Public comm As OleDbCommand
Public reader As OleDbDataReader
Public query As String
Public count As Integer
End Module
(Can't add this post on my first post because it reached it's max capacity :P)

Here's the slightly changed Received function:
'receive msg from client
Private Sub Recieve(ByVal ar As IAsyncResult)
Try
Dim ns As NetworkStream = CType(ar.AsyncState, NetworkStream)
Dim message As String = ""
ByteSize = ns.EndRead(ar)
message = String.Concat(message, System.Text.ASCIIEncoding.ASCII.GetString(byteData, 0, ByteSize))
ns.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf Recieve), ns)
'if there are still data left in the network stream
While ns.DataAvailable
ns.BeginRead(byteData, 0, byteData.Length, New AsyncCallback(AddressOf Recieve), ns)
End While
Invoke(New _Read(AddressOf Read), message)
Catch ex As Exception
'check for Disconnection or Force Disconnection
Invoke(New _dc(AddressOf dc))
End Try
End Sub
I saw on the MS Documentation about NetworkStream.EndRead that the EndRead comes first before BeginRead. Maybe it is only applicable on Read.
NetworkStream.EndRead Method (IAsyncResult)
But the problem still persist :(

Related

How to get ipv4 addresses of all computers on a network in VB.NET

I have a Windows Forms app in Visual basic that is currently sending messages back and forth between two computers. Currently, the user has to manually enter the ipv4 address of the receiver of the message. what I would like to do is put the ipv4 addresses of all the computers on the network into a combo box so the user has a list to pick from.
I have searched a whole bunch of different forums and am unable to find a working solution.
Public Class Form1
Dim strHostName As String
Dim strIPAddress As String
Dim running As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
strHostName = System.Net.Dns.GetHostName()
strIPAddress = System.Net.Dns.GetHostByName(strHostName).AddressList(0).ToString()
Me.Text = strIPAddress
txtIP.Text = strIPAddress
running = True
'run listener on separate thread
Dim listenTrd As Thread
listenTrd = New Thread(AddressOf StartServer)
listenTrd.IsBackground = True
listenTrd.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As EventArgs) Handles MyBase.FormClosing
running = False
End Sub
Sub StartServer()
Dim serverSocket As New TcpListener(CInt(txtPort.Text))
Dim requestCount As Integer
Dim clientSocket As TcpClient
Dim messageReceived As Boolean = False
While running
messageReceived = False
serverSocket.Start()
msg("Server Started")
clientSocket = serverSocket.AcceptTcpClient()
msg("Accept connection from client")
requestCount = 0
While (Not (messageReceived))
Try
requestCount = requestCount + 1
Dim networkStream As NetworkStream = clientSocket.GetStream()
Dim bytesFrom(10024) As Byte
networkStream.Read(bytesFrom, 0, bytesFrom.Length)
Dim dataFromClient As String = System.Text.Encoding.ASCII.GetString(bytesFrom)
dataFromClient = dataFromClient.Substring(0, dataFromClient.Length)
'invoke into other thread
txtOut.Invoke(Sub()
txtOut.Text += dataFromClient
txtOut.Text += vbNewLine
End Sub)
messageReceived = True
Dim serverResponse As String = "Server response " + Convert.ToString(requestCount)
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
networkStream.Write(sendBytes, 0, sendBytes.Length)
networkStream.Flush()
Catch ex As Exception
End
End Try
End While
clientSocket.Close()
serverSocket.Stop()
msg("exit")
Console.ReadLine()
End While
End Sub
Sub msg(ByVal mesg As String)
mesg.Trim()
Console.WriteLine(" >> " + mesg)
End Sub
Public Sub WriteData(ByVal data As String, ByRef IP As String)
Try
txtOut.Text += data.PadRight(1)
txtOut.Text += vbNewLine
txtMsg.Clear()
Console.WriteLine("Sending message """ & data & """ to " & IP)
Dim client As TcpClient = New TcpClient()
client.Connect(New IPEndPoint(IPAddress.Parse(IP), CInt(txtPort.Text)))
Dim stream As NetworkStream = client.GetStream()
Dim sendBytes As Byte() = Encoding.ASCII.GetBytes(data)
stream.Write(sendBytes, 0, sendBytes.Length)
Catch ex As Exception
msg(ex.ToString)
End Try
End Sub
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
If Not (txtMsg.Text = vbNullString) AndAlso Not (txtIP.Text = vbNullString) Then
WriteData(txtMsg.Text, txtIP.Text)
End If
End Sub
Private Sub txtMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles txtMsg.KeyDown
If e.KeyCode = Keys.Enter Then
If Not (txtMsg.Text = vbNullString) AndAlso Not (txtIP.Text = vbNullString) Then
WriteData(txtMsg.Text, txtIP.Text)
End If
End If
End Sub
Private Sub BtnFind_Click(sender As Object, e As EventArgs) Handles btnFind.Click
'find all local addresses and put in combobox (button will be removed later)
End Sub
End Class
For PC names "as you suggested in your comments", I used this at work to get pc names i was on domain, try it:
AFAIK it works on domains...
Make sure you have a listbox on your form, or change listbox and populate in your combobox directly, play with that as you like :)
Private Delegate Sub UpdateDelegate(ByVal s As String)
Dim t As New Threading.Thread(AddressOf GetNetworkComputers)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
t.IsBackground = True
t.Start()
End Sub
Private Sub AddListBoxItem(ByVal s As String)
ListBox1.Items.Add(s)
End Sub
Private Sub GetNetworkComputers()
Try
Dim alWorkGroups As New ArrayList
Dim de As New DirectoryEntry
de.Path = "WinNT:"
For Each d As DirectoryEntry In de.Children
If d.SchemaClassName = "Domain" Then alWorkGroups.Add(d.Name)
d.Dispose()
Next
For Each workgroup As String In alWorkGroups
de.Path = "WinNT://" & workgroup
For Each d As DirectoryEntry In de.Children
If d.SchemaClassName = "Computer" Then
Dim del As UpdateDelegate = AddressOf AddListBoxItem
Me.Invoke(del, d.Name)
End If
d.Dispose()
Next
Next
Catch ex As Exception
'MsgBox(Ex.Message)
End Try
End Sub
POC:

cancelling async task using progress bar causes targetinvocationexception error using vb.net

I am trying to load a datatable async so that the UI remains responsive. I've used the dt.RowChanged event to handle reporting progress back to the progress bar and label. But when the Stop button is clicked, it causes the following error:
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll.
I'm not sure how to find my way around this issue. Any guidance is appreciated. The following is code from sample project using AdventureWorks DB
Imports System.Threading
Imports System.Threading.Tasks
Public Class AsyncProgressCancel
Public strConnectionString As String = "data source=010XXX01;initial catalog=AdventureWorks2012;integrated security=SSPI;"
Private dt As DataTable
Private ds As DataSet
Dim dataset
Dim RecordCount As Integer = 1000000
Dim Counter As Integer
Dim myProgress As Progress(Of Integer)
Private Delegate Sub AsyncDelegate(ByVal value As Integer)
Private ProgressUpdater As New AsyncDelegate(AddressOf UpdateProgress)
Private TargetCounter As Integer = 1000
Private cts As CancellationTokenSource
Private Cancelled As Boolean
Private Sub AsyncProgressCancel_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ProgressBar1.Visible = False
lblProgress.Visible = False
btnStop.Enabled = False
End Sub
Private Async Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
btnStart.Enabled = False
btnStop.Enabled = True
Cancelled = False
ProgressBar1.Value = 0
ProgressBar1.Maximum = RecordCount
ProgressBar1.Visible = True
lblProgress.Visible = True
DataGridView1.Enabled = False
cts = New CancellationTokenSource()
Try
Dim completed As Boolean = Await LoadDataAsync(myProgress, cts.Token)
Catch ex As OperationCanceledException
lblProgress.Text = "Retrieve cancelled."
DataGridView1.DataSource = Nothing
DataGridView1.Enabled = True
btnStop.Enabled = False
btnStart.Enabled = True
ProgressBar1.Visible = False
Catch ex As Exception
MsgBox(ex)
End Try
End Sub
Private Sub UpdateProgress(ByVal value As Integer)
If Cancelled = True Then
cts.Cancel()
Else
If ProgressBar1.InvokeRequired Then
ProgressBar1.Invoke(ProgressUpdater, New Object() {value})
ElseIf value > ProgressBar1.Maximum Then
value = ProgressBar1.Maximum
ProgressBar1.Value = value
End If
lblProgress.Text = Math.Round((value / RecordCount) * 100).ToString & "% complete" '"Step Number: " & myInt.ToString
ProgressBar1.Value = value
End If
End Sub
Private Async Function LoadDataAsync(ByVal myProgress As IProgress(Of Integer), token As CancellationToken) As Task(Of Boolean)
Dim comSQL As SqlClient.SqlCommand
Dim strSQL As String
Dim da As SqlClient.SqlDataAdapter
Dim dt As New DataTable
Dim ReturnValue As Boolean
Try
DataGridView1.Enabled = Await Task(Of Boolean).Run(Function()
Using conn As SqlClient.SqlConnection = New SqlClient.SqlConnection(strConnectionString)
conn.Open()
strSQL = "SELECT * FROM (SELECT TOP 1000000 PRODUCTION.PRODUCT.* FROM sales.SalesOrderDetail CROSS JOIN production.Product) A"
comSQL = New SqlClient.SqlCommand(strSQL, conn)
da = New SqlClient.SqlDataAdapter(comSQL)
AddHandler dt.RowChanged, Sub(obj, e)
If e.Action.Add Then
Counter = obj.Rows.Count
If Counter > RecordCount Then
Counter = RecordCount
Else
Counter = Counter + 1 ' Math.Ceiling(0.1 * RecordCount)
End If
End If
If token.IsCancellationRequested = True Then
token.ThrowIfCancellationRequested()
Else
If Counter = TargetCounter Then
UpdateProgress(Counter)
TargetCounter = TargetCounter + 1000
End If
End If
End Sub
If Counter > 0 Then
myProgress.Report(Counter)
End If
da.Fill(dt)
dataset = dt
ReturnValue = True
Return ReturnValue
End Using
End Function, token)
Catch ex As Exception
MsgBox(ex)
End Try
End Function
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Try
If Not cts Is Nothing Then
cts.Cancel()
End If
Catch ex As Exception
MsgBox(ex)
End Try
End Sub
End Class

How do I close the tcp client (client.close) with a button?

I have a client server application.
if the client has disconnected the server can detect it automatically and remove it from the connected clients list.
I am going to focus on the server now.
I would like to have a Stop Server button. To stop the Listener and Tcp Client Connections.
I can easily stop the listener, but I am having a hard time trying to figure out how to stop the tcp client ( or issue a Client.Close )
[SERVER]
Public Class Server
Dim ClientList As New Hashtable
Dim Listener As TcpListener
Dim ListenerThread As System.Threading.Thread
Private Sub ButtonStart_Click(sender As Object, e As EventArgs) Handles ButtonStart.Click
ListenerThread = New System.Threading.Thread(AddressOf Listen)
ListenerThread.IsBackground = True
ListenerThread.Start(TextBoxPort.Text)
ButtonStart.Enabled = False
ButtonStop.Enabled = True
ListBox1.Items.Add("[SERVER] Waiting For A Connection...")
End Sub
Sub ClientDisconnected(ByVal Client As ConnectedClient)
ClientList.Remove(Client) 'remove the client from the hashtable
ListBox2.Items.Remove(Client.Name) 'remove it from our listbox
End Sub
Sub Listen(ByVal Port As Integer)
Try
Listener = New TcpListener(IPAddress.Any, Port)
Listener.Start()
Do
Dim Client As New ConnectedClient(Listener.AcceptTcpClient)
AddHandler Client.ReceivedMessage, AddressOf ReceivedMessage
AddHandler Client.ClientDisconnected, AddressOf ClientDisconnected
Loop Until False
Catch
End Try
End Sub
Dim TotalItemCount As String
Sub ReceivedMessage(ByVal Msg As String, ByVal Client As ConnectedClient)
Dim Message() As String = Msg.Split("|")
Select Case Message(0)
Case "CHAT" 'if it's CHAT
ListBox1.Items.Add(Client.Name & " Says: " & " " & Message(1))
Case "SAVETRAN"
ListBox1.Items.Add("Transaction Number: " + Message(1) + vbCrLf + "Customer Number: " + Message(2))
Case "TRANDETAIL"
ListBox1.Items.Add("Barcode: " + Message(1) + vbCrLf + "Quantity: " + Message(2) + vbCrLf + "Price Sold: " + Message(3))
ProgressBar1.Value += 1
Label1.Text = ProgressBar1.Value
If Label1.Text = ProgressBar1.Maximum Then
ProgressBar1.Value = 0
End If
Case "ITEMCOUNT"
ListBox1.Items.Add("SERVER IS EXPECTED TO RECEIVE " + Message(1) + " ITEMS.")
TotalItemCount = Message(1)
ProgressBar1.Maximum = TotalItemCount
Case "LOGIN" 'A client has connected
ClientList.Add(Client, Client.Name)
ListBox2.Items.Add(Client.Name)
End Select
End Sub
Private Sub ButtonStop_Click(sender As Object, e As EventArgs) Handles ButtonStop.Click
Listener.Stop()
ListBox1.Items.Add("Server Stopped")
ButtonStop.Enabled = False
ButtonStart.Enabled = True
End Sub
Private Sub Server_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
End Sub
End Class
In the Server Application there is a class call ConnectedClient
[Connected Client]
Public Class ConnectedClient
Public Cli As TcpClient
Private UniqueID As String
Public Property Name
Get
Return UniqueID
End Get
Set(ByVal Value)
UniqueID = Value
End Set
End Property
Public Sub New(Client As TcpClient)
Dim r As New Random
Dim x As String = String.Empty
For i = 0 To 7
x &= Chr(r.Next(65, 89))
Next
Me.Name = Client.Client.RemoteEndPoint.ToString().Remove(Client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & x
Cli = Client
Cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
End Sub
Public Event ReceivedMessage(ByVal Message As String, ByVal Client As ConnectedClient)
Public Event ClientDisconnected(ByVal Client As ConnectedClient)
Sub Reading(ByVal AR As IAsyncResult)
Try
Dim Reader As New StreamReader(Cli.GetStream)
Dim Msg As String = Reader.ReadLine()
RaiseEvent ReceivedMessage(Msg, Me)
Cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
Catch ex As Exception
'Try and read again
Try
Dim Reader As New StreamReader(Cli.GetStream)
Dim Msg As String = Reader.ReadLine()
RaiseEvent ReceivedMessage(Msg, Me)
Cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
Catch
RaiseEvent ClientDisconnected(Me)
End Try
End Try
End Sub
Sub SendData(ByVal Message As String)
Dim Writer As New StreamWriter(Cli.GetStream)
Writer.WriteLine(Message)
Writer.Flush()
End Sub
End Class
I was trying somehow to link to the connected client class and get the Client.Close, but I cannot
figure it out.

Issue with socket chat not being able to send full messages

I am having a little issue with this socket chat, if I send little messages like "hello world" it works perfectly fine but if I try to send huge messages with about 10,000 characters it just crashes, i've been trying to fix this for the past 3 days with no luck, what should I be doing?
Server source:
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Enum Command
Login
'Log into the server
Logout
'Logout of the server
Message
'Send a text message to all the chat clients
List
'Get a list of users in the chat room from the server
Null
'No command
End Enum
Public Class Form1
'The ClientInfo structure holds the required information about every
'client connected to the server
Private Structure ClientInfo
Public socket As Socket
'Socket of the client
Public strName As String
'Name by which the user logged into the chat room
End Structure
'The collection of all clients logged into the room (an array of type ClientInfo)
Private clientList As ArrayList
'The main socket on which the server listens to the clients
Private serverSocket As Socket
Private byteData As Byte() = New Byte(1023) {}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
clientList = New ArrayList()
'We are using TCP sockets
serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Assign the any IP of the machine and listen on port number 1000
Dim ipEndPoint As New IPEndPoint(IPAddress.Any, 2277)
'Bind and listen on the given address
serverSocket.Bind(ipEndPoint)
serverSocket.Listen(4)
'Accept the incoming clients
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
Catch ex As Exception
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try
End Sub
Private Sub OnAccept(ar As IAsyncResult)
Try
Dim clientSocket As Socket = serverSocket.EndAccept(ar)
'Start listening for more clients
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
'Once the client connects then start receiving the commands from her
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), clientSocket)
Catch ex As Exception
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try
End Sub
Private Sub OnReceive(ar As IAsyncResult)
Try
Dim clientSocket As Socket = DirectCast(ar.AsyncState, Socket)
clientSocket.EndReceive(ar)
'Transform the array of bytes received from the user into an
'intelligent form of object Data
Dim msgReceived As New Data(byteData)
'We will send this object in response the users request
Dim msgToSend As New Data()
Dim message As Byte()
'If the message is to login, logout, or simple text message
'then when send to others the type of the message remains the same
msgToSend.cmdCommand = msgReceived.cmdCommand
msgToSend.strName = msgReceived.strName
Select Case msgReceived.cmdCommand
Case Command.Login
'When a user logs in to the server then we add her to our
'list of clients
Dim clientInfo As New ClientInfo()
clientInfo.socket = clientSocket
clientInfo.strName = msgReceived.strName
clientList.Add(clientInfo)
'Set the text of the message that we will broadcast to all users
msgToSend.strMessage = "<<<" & msgReceived.strName & " has joined the room>>>"
Exit Select
Case Command.Logout
'When a user wants to log out of the server then we search for her
'in the list of clients and close the corresponding connection
Dim nIndex As Integer = 0
For Each client As ClientInfo In clientList
If client.socket Is clientSocket Then
clientList.RemoveAt(nIndex)
Exit For
End If
nIndex += 1
Next
clientSocket.Close()
msgToSend.strMessage = "<<<" & msgReceived.strName & " has left the room>>>"
Exit Select
Case Command.Message
'Set the text of the message that we will broadcast to all users
msgToSend.strMessage = msgReceived.strName & ": " & msgReceived.strMessage
Exit Select
Case Command.List
'Send the names of all users in the chat room to the new user
msgToSend.cmdCommand = Command.List
msgToSend.strName = Nothing
msgToSend.strMessage = Nothing
'Collect the names of the user in the chat room
For Each client As ClientInfo In clientList
'To keep things simple we use asterisk as the marker to separate the user names
msgToSend.strMessage += client.strName & "*"
Next
message = msgToSend.ToByte()
'Send the name of the users in the chat room
clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), clientSocket)
Exit Select
End Select
If msgToSend.cmdCommand <> Command.List Then
'List messages are not broadcasted
message = msgToSend.ToByte()
For Each clientInfo As ClientInfo In clientList
If clientInfo.socket IsNot clientSocket OrElse msgToSend.cmdCommand <> Command.Login Then
'Send the message to all users
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSend), clientInfo.socket)
End If
Next
Debug.Print(msgToSend.strMessage)
End If
'If the user is logging out then we need not listen from her
If msgReceived.cmdCommand <> Command.Logout Then
'Start listening to the message send by the user
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), clientSocket)
End If
Catch ex As Exception
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try
End Sub
Public Sub OnSend(ar As IAsyncResult)
Try
Dim client As Socket = DirectCast(ar.AsyncState, Socket)
client.EndSend(ar)
Catch ex As Exception
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.[Error])
End Try
End Sub
End Class
'The data structure by which the server and the client interact with
'each other
Class Data
Public strName As String
'Name by which the client logs into the room
Public strMessage As String
'Message text
Public cmdCommand As Command
'Command type (login, logout, send message, etcetera)
'Default constructor
Public Sub New()
cmdCommand = Command.Null
strMessage = Nothing
strName = Nothing
End Sub
'Converts the bytes into an object of type Data
Public Sub New(data__1 As Byte())
'The first four bytes are for the Command
cmdCommand = CType(BitConverter.ToInt32(data__1, 0), Command)
'The next four store the length of the name
Dim nameLen As Integer = BitConverter.ToInt32(data__1, 4)
'The next four store the length of the message
Dim msgLen As Integer = BitConverter.ToInt32(data__1, 8)
'This check makes sure that strName has been passed in the array of bytes
If nameLen > 0 Then
Me.strName = Encoding.UTF8.GetString(data__1, 12, nameLen)
Else
Me.strName = Nothing
End If
'This checks for a null message field
If msgLen > 0 Then
Me.strMessage = Encoding.UTF8.GetString(data__1, 12 + nameLen, msgLen)
Else
Me.strMessage = Nothing
End If
End Sub
'Converts the Data structure into an array of bytes
Public Function ToByte() As Byte()
Dim result As New List(Of Byte)()
'First four are for the Command
result.AddRange(BitConverter.GetBytes(CInt(cmdCommand)))
'Add the length of the name
If strName IsNot Nothing Then
result.AddRange(BitConverter.GetBytes(strName.Length))
Else
result.AddRange(BitConverter.GetBytes(0))
End If
'Length of the message
If strMessage IsNot Nothing Then
result.AddRange(BitConverter.GetBytes(strMessage.Length))
Else
result.AddRange(BitConverter.GetBytes(0))
End If
'Add the name
If strName IsNot Nothing Then
result.AddRange(Encoding.UTF8.GetBytes(strName))
End If
'And, lastly we add the message text to our array of bytes
If strMessage IsNot Nothing Then
result.AddRange(Encoding.UTF8.GetBytes(strMessage))
End If
Return result.ToArray()
End Function
End Class
Client source:
Enum Command
Login '0 Log into the server
Logout '1 Logout of the server
Message '2 Send a text message to all the chat clients
List '3 Get a list of users in the chat room from the server
Null '4 No command
End Enum
Public Class frmMain
Public clientSocket As System.Net.Sockets.Socket
'The main client socket
Public strName As String
'Name by which the user logs into the room
Private byteData As Byte() = New Byte(1023) {}
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call StartChat()
End Sub
Private Sub StartChat()
clientSocket = New System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp)
Dim ipAddress As System.Net.IPAddress = System.Net.IPAddress.Parse("127.0.0.1")
Dim ipEndPoint As New System.Net.IPEndPoint(ipAddress, 2277)
clientSocket.BeginConnect(ipEndPoint, New AsyncCallback(AddressOf OnLoginConnect), Nothing)
End Sub
Private Sub OnLoginConnect(ar As IAsyncResult)
clientSocket.EndConnect(ar)
'We are connected so we login into the server
Dim msgToSend As New Data()
msgToSend.cmdCommand = Command.Login
msgToSend.strName = txtUser.Text
msgToSend.strMessage = Nothing
Dim b As Byte() = msgToSend.ToByte()
'Send the message to the server
clientSocket.BeginSend(b, 0, b.Length, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf OnLoginSend), Nothing)
End Sub
Private Sub OnLoginSend(ar As IAsyncResult)
clientSocket.EndSend(ar)
strName = txtUser.Text
Call LoggedIn()
End Sub
'***************
Private Sub LoggedIn()
'The user has logged into the system so we now request the server to send
'the names of all users who are in the chat room
Dim msgToSend As New Data()
msgToSend.cmdCommand = Command.List
msgToSend.strName = strName
msgToSend.strMessage = Nothing
byteData = msgToSend.ToByte()
clientSocket.BeginSend(byteData, 0, byteData.Length, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf OnSend), Nothing)
byteData = New Byte(1023) {}
'Start listening to the data asynchronously
clientSocket.BeginReceive(byteData, 0, byteData.Length, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf OnReceive), Nothing)
End Sub
'Broadcast the message typed by the user to everyone
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
'Fill the info for the message to be send
Dim msgToSend As New Data()
'.ToString("M/d/yyyy h:mm:ss tt")
msgToSend.strName = "[" & Date.Now.ToString("h:mm:ss tt") & "] <" & strName & ">"
msgToSend.strMessage = txtMessage.Text
msgToSend.cmdCommand = Command.Message
Dim byteData As Byte() = msgToSend.ToByte()
'Send it to the server
clientSocket.BeginSend(byteData, 0, byteData.Length, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf OnSend), Nothing)
txtMessage.Text = Nothing
End Sub
Private Sub OnSend(ar As IAsyncResult)
clientSocket.EndSend(ar)
End Sub
Private Sub OnReceive(ar As IAsyncResult)
'clientSocket.EndReceive(ar)
Dim bytesReceived As Long = clientSocket.EndReceive(ar)
If (bytesReceived > 0) Then
Me.Invoke(New iThreadSafe(AddressOf iThreadSafeFinish), New Object() {byteData})
End If
byteData = New Byte(1023) {}
clientSocket.BeginReceive(byteData, 0, byteData.Length, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf OnReceive), Nothing)
End Sub
Private Delegate Sub iThreadSafe(ByVal ibyteData As Byte())
Private Sub iThreadSafeFinish(ByVal ibyteData As Byte())
Dim msgReceived As New Data(ibyteData)
'Accordingly process the message received
Debug.Print(msgReceived.cmdCommand)
Select Case msgReceived.cmdCommand
Case 0 'login
lstChatters.Items.Add(msgReceived.strName)
Exit Select
Case 1 'log out
lstChatters.Items.Remove(msgReceived.strName)
Exit Select
Case 2 'msg
Exit Select
Case 3 'List
lstChatters.Items.AddRange(msgReceived.strMessage.Split("*"c))
lstChatters.Items.RemoveAt(lstChatters.Items.Count - 1)
txtChatBox.Text += "<<<" & strName & " has joined the room>>>" & vbCr & vbLf
Exit Select
End Select
If msgReceived.strMessage IsNot Nothing AndAlso msgReceived.cmdCommand <> Command.List Then
txtChatBox.Text += msgReceived.strMessage & vbCr & vbLf
End If
End Sub
Private Sub txtMessage_TextChanged(sender As Object, e As KeyEventArgs) Handles txtMessage.KeyDown
If e.KeyCode = Keys.Enter Then
btnSend_Click(sender, Nothing)
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
strName = txtUser.Text
End Sub
End Class
'The data structure by which the server and the client interact with
'each other
Class Data
Public strName As String
'Name by which the client logs into the room
Public strMessage As String
'Message text
Public cmdCommand As Command
'Command type (login, logout, send message, etcetera)
'Default constructor
Public Sub New()
cmdCommand = Command.Null
strMessage = Nothing
strName = Nothing
End Sub
'Converts the bytes into an object of type Data
Public Sub New(data__1 As Byte())
'The first four bytes are for the Command
cmdCommand = CType(BitConverter.ToInt32(data__1, 0), Command)
'The next four store the length of the name
Dim nameLen As Integer = BitConverter.ToInt32(data__1, 4)
'The next four store the length of the message
Dim msgLen As Integer = BitConverter.ToInt32(data__1, 8)
'This check makes sure that strName has been passed in the array of bytes
If nameLen > 0 Then
strName = System.Text.Encoding.UTF8.GetString(data__1, 12, nameLen)
Else
strName = Nothing
End If
'This checks for a null message field
If msgLen > 0 Then
strMessage = System.Text.Encoding.UTF8.GetString(data__1, 12 + nameLen, msgLen)
Else
strMessage = Nothing
End If
End Sub
'Converts the Data structure into an array of bytes
Public Function ToByte() As Byte()
Dim result As New List(Of Byte)()
'First four are for the Command
result.AddRange(BitConverter.GetBytes(CInt(cmdCommand)))
'Add the length of the name
If strName IsNot Nothing Then
result.AddRange(BitConverter.GetBytes(strName.Length))
Else
result.AddRange(BitConverter.GetBytes(0))
End If
'Length of the message
If strMessage IsNot Nothing Then
result.AddRange(BitConverter.GetBytes(strMessage.Length))
Else
result.AddRange(BitConverter.GetBytes(0))
End If
'Add the name
If strName IsNot Nothing Then
result.AddRange(System.Text.Encoding.UTF8.GetBytes(strName))
End If
'And, lastly we add the message text to our array of bytes
If strMessage IsNot Nothing Then
result.AddRange(System.Text.Encoding.UTF8.GetBytes(strMessage))
End If
Return result.ToArray()
End Function
End Class
You are assuming that you will receive an entire message at a time. TCP does not guarantee to preserve the chunks that you wrote. Use the return value bytesReceived to determine how many bytes are actually in the buffer.
Your code must be able to deal with the possibility of receiving all outstanding data one byte at a time.

vb.net server Socket dismiss previous client after new accepting new client

as i told in title , server doesnt listen previous client's packets. I
just need server to read all packets coming from multiple clients.
here s my code , thanks for your help
serverSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
Dim ipAddress As IPAddress = ipAddress.Parse("192.168.2.202")
Dim IpEndPoint As IPEndPoint = New IPEndPoint(ipAddress, 15002)
serverSocket.Bind(IpEndPoint)
serverSocket.Listen(1500)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
Delegate Sub _OnAccept(ByVal ar As IAsyncResult)
Private Sub OnAccept(ByVal ar As IAsyncResult)
If InvokeRequired Then
Invoke(New _OnAccept(AddressOf OnAccept), ar)
Exit Sub
End If
clientSocket = serverSocket.EndAccept(ar)
serverSocket.BeginAccept(New AsyncCallback(AddressOf OnAccept), Nothing)
Try
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnRecieve),
clientSocket)
Catch ex As Exception
End Try
AddClient(clientSocket)
End Sub
Delegate Sub _AddClient(ByVal client As Socket) 'delege used to invoke AddCLient()
Private Sub AddClient(ByVal client As Socket)
If InvokeRequired Then
Invoke(New _AddClient(AddressOf AddClient), client)
Exit Sub
End If
Dim lvi As New ListViewItem(client.LocalEndPoint.ToString)
lvi.Tag = client
ListBox1.Items.Add(client.RemoteEndPoint.ToString & " Bağlandı")
End Sub
Delegate Sub _OnRecieve(ByVal ar As IAsyncResult)
Private Sub OnRecieve(ByVal ar As IAsyncResult)
If InvokeRequired Then
Invoke(New _OnRecieve(AddressOf OnRecieve), ar)
Exit Sub
End If
Dim client As Socket = ar.AsyncState
Try
client.EndReceive(ar)
Catch ex As Exception
End Try
Dim bytesRec As Byte() = byteData
Dim paket As String = System.Text.ASCIIEncoding.ASCII.GetString(bytesRec)
Dim temizip As String
temizip = Replace(paket, Chr(0), Chr(32))
temizip = temizip.Trim
Dim msg As String = temizip
Try
Dim boyut As Integer
boyut = msg(0) & msg(1)
boyut = boyut - 10
Dim externalip As String
externalip = msg.Remove(0, 2)
externalip = externalip.Remove(boyut, (externalip.Length - boyut))
If clientlist.Contains(externalip) Then
Else
clientlist.Add(externalip)
End If
Catch ex As Exception
End Try
Try
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnRecieve),
clientSocket)
Catch ex As Exception
End Try
End Sub
thanks people i solved this , i declare new clientsocket for each client and its solved.
i just delete clientSocket variable from the header code , and i re-declared it on every thread.