|
-
Mar 20th, 2002, 09:44 AM
#1
JpEgy - Working TCP class!!
got it working JpEgy. Here it is
Code:
' Thanks goes out to my hommies at www.vbforums.com!
' Special Thanks To:
' JpEgy for fixing many minor mistakes and being the first tester.
Imports System
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic
Namespace Sockets
' All socket connection types
Namespace TCP
Public Class TCPConnection
' For TCP connections intercepted by the TcpListener
Private tcpConn As TcpClient
Private m_requestID As Guid = Guid.NewGuid
Private objClient As TcpClient
Private arData(1024) As Byte
Private m_ClientIP As String
Private m_State As Short
Private objText As New StringBuilder()
Public Event Connected(ByVal sender As TCPConnection)
Public Event Disconnected(ByVal sender As TCPConnection)
Public Event DataReceived(ByVal sender As TCPConnection, ByVal Data As String, ByVal BytesReceived As Long)
Public Event SockError(ByVal strMessage As String)
Public Sub New(ByVal client As TcpClient)
' A new instance of the class started meaning a new connection
objClient = client
RaiseEvent Connected(Me)
Console.Writeline("Test")
m_State = 1
objClient.GetStream.BeginRead(arData, 0, 1024, _
AddressOf Receive, Nothing)
End Sub
Public Sub SendData(ByVal Data As String)
' Server sending to client. String Data
m_State = 3
SyncLock objClient.GetStream
Dim w As New IO.StreamWriter(objClient.GetStream)
w.Write(Data)
w.Flush()
End SyncLock
m_State = 1
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
' Start the data receiving process
Dim intCount As Integer
Console.Writeline("Received")
Try
SyncLock objClient.GetStream
intCount = objClient.GetStream.EndRead(ar)
End SyncLock
If intCount < 1 Then
RaiseEvent Disconnected(Me)
m_State = 0
Exit Sub
End If
BuildString(arData, 0, intCount)
SyncLock objClient.GetStream
objClient.GetStream.BeginRead(arData, 0, 1024, AddressOf Receive, Nothing)
End SyncLock
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
RaiseEvent Disconnected(Me)
m_State = 0
End Try
End Sub
Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
Dim intIndex As Integer
Dim txt As String
Console.Writeline("BuildString")
m_State = 2
objText = New StringBuilder()
For intIndex = offset To offset + count - 1
txt = ChrW(Bytes(intIndex))
objText.Append(txt)
Next
RaiseEvent DataReceived(Me, objText.ToString, objText.Length)
m_State = 1
End Sub
Public ReadOnly Property requestID() As String
' A connections requestID to identify it.
Get
Return m_requestID.ToString
End Get
End Property
Public ReadOnly Property ClientIP() As String
' The ip address of the connected client
Get
Return m_ClientIP
End Get
End Property
Public ReadOnly Property State() As Short
' The ip address of the connected client
' Possible values:
' 0 - Disconnected
' 1 - Connected And Ready
' 2 - Receiving
' 3 - Sending
' 4 - Connecting
Get
Return m_State
End Get
End Property
Public Sub Connect(ByVal strDomain As String, ByVal intPort As Integer)
m_State = 4
Try
objClient = New TcpClient(strDomain, intPort)
RaiseEvent Connected(Me)
m_State = 1
objClient.ReceiveBufferSize = 1024
objClient.NoDelay = True
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
m_State = 0
End Try
End Sub
End Class
End Namespace
End Namespace
-
Mar 20th, 2002, 02:44 PM
#2
Update
Sending was broken..it is fixed now..
Code:
' Thanks goes out to my hommies at www.vbforums.com!
' Special Thanks To:
' JpEgy for fixing many minor mistakes and being the first tester.
' This file written with TextPad... Who needs Visual Studio?
Option Explicit
Imports System
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic
Namespace Sockets
' All socket connection types
Namespace TCP
Public Class TCPConnection
' For TCP connections intercepted by the TcpListener
Private tcpConn As TcpClient
Private m_requestID As Guid = Guid.NewGuid
Private objClient As TcpClient
Private arData(1024) As Byte
Private m_ClientIP As String
Private m_State As Short
Private objText As New StringBuilder()
Public Event Connected(ByVal sender As TCPConnection)
Public Event Disconnected(ByVal sender As TCPConnection)
Public Event DataReceived(ByVal sender As TCPConnection, ByVal Data As String, ByVal BytesReceived As Long)
Public Event SockError(ByVal strMessage As String)
Public Sub New(ByVal client As TcpClient)
' A new instance of the class started meaning a new connection
objClient = client
'RaiseEvent Connected(Me)
'Console.Writeline("Test")
m_State = 1
objClient.GetStream.BeginRead(arData, 0, 1024, _
AddressOf Receive, Nothing)
End Sub
Public Sub SendData(ByVal Data As String)
' Server sending to client. String Data
m_State = 3
objClient.Send(Encoding.ASCII.GetBytes(Data))
m_State = 1
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
' Start the data receiving process
Dim intCount As Integer
Console.Writeline("Received")
Try
SyncLock objClient.GetStream
intCount = objClient.GetStream.EndRead(ar)
End SyncLock
If intCount < 1 Then
RaiseEvent Disconnected(Me)
m_State = 0
Exit Sub
End If
BuildString(arData, 0, intCount)
SyncLock objClient.GetStream
objClient.GetStream.BeginRead(arData, 0, 1024, AddressOf Receive, Nothing)
End SyncLock
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
RaiseEvent Disconnected(Me)
m_State = 0
End Try
End Sub
Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
Dim intIndex As Integer
Dim txt As String
Console.Writeline("BuildString")
m_State = 2
objText = New StringBuilder()
For intIndex = offset To offset + count - 1
txt = ChrW(Bytes(intIndex))
objText.Append(txt)
Next
RaiseEvent DataReceived(Me, objText.ToString, objText.Length)
m_State = 1
End Sub
Public ReadOnly Property requestID() As String
' A connections requestID to identify it.
' This property returns a Guid. Use this to identify a specific
' client when using as as multi-connection server. You can
' store the class reference into a collection or hashtable
' and use the requestID as the unique key.
Get
Return m_requestID.ToString
End Get
End Property
Public ReadOnly Property ClientIP() As String
' The ip address of the connected client
Get
Return m_ClientIP
End Get
End Property
Public ReadOnly Property State() As Short
' The ip address of the connected client
' Possible values:
' 0 - Disconnected
' 1 - Connected And Ready
' 2 - Receiving
' 3 - Sending
' 4 - Connecting
Get
Return m_State
End Get
End Property
Public Sub Connect(ByVal strDomain As String, ByVal intPort As Integer)
m_State = 4
Try
objClient = New TcpClient(strDomain, intPort)
RaiseEvent Connected(Me)
m_State = 1
objClient.ReceiveBufferSize = 1024
objClient.NoDelay = True
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
m_State = 0
End Try
End Sub
End Class
End Namespace
End Namespace
-
Mar 21st, 2002, 09:17 AM
#3
Frenzied Member
Hey Cander, could you comment this code.
I have never done any network programming and would really like to know what is going on in this code.
Never too late to learn something new. 
Thanks
Dont gain the world and lose your soul
-
Mar 21st, 2002, 09:22 AM
#4
Sure thing, I will work on it this afternoon to add more comments. I
-
Mar 21st, 2002, 12:15 PM
#5
ok ive added some comments that i hope will explain some of it better
VB Code:
' Thanks goes out to my hommies at [url]www.vbforums.com[/url]!
' Special Thanks To:
' JpEgy for fixing many minor mistakes and being the first tester.
' This file written with TextPad... Who needs Visual Studio?
Option Explicit
Imports System
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic
Namespace Sockets
' All socket connection types
Namespace TCP
Public Class TCPConnection
' For TCP connections intercepted by the TcpListener
Private tcpConn As TcpClient
Private m_requestID As Guid = Guid.NewGuid
Private objClient As TcpClient
Private arData(1024) As Byte
Private m_ClientIP As String
Private m_State As Short
Private objText As New StringBuilder()
Public Event Connected(ByVal sender As TCPConnection)
Public Event Disconnected(ByVal sender As TCPConnection)
Public Event DataReceived(ByVal sender As TCPConnection, ByVal Data As String, ByVal BytesReceived As Long)
Public Event SockError(ByVal strMessage As String)
Public Sub New(ByVal client As TcpClient)
' A new instance of the class started meaning a new connection
' New is a constructor that it called when New is used with creating
' A class instance
objClient = client
'RaiseEvent Connected(Me)
'Console.Writeline("Test")
m_State = 1
' Have the TcpClient object listen in the background for incoming
' data and call the Receive sub whenit does.
objClient.GetStream.BeginRead(arData, 0, 1024, _
AddressOf Receive, Nothing)
End Sub
Public Sub SendData(ByVal Data As String)
' Server sending to client. String Data
m_State = 3
' Send the string of Data to the client
objClient.Send(Encoding.ASCII.GetBytes(Data))
m_State = 1
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
' Start the data receiving process
Dim intCount As Integer
Console.Writeline("Received")
Try
' check for an error while receiving data
SyncLock objClient.GetStream
intCount = objClient.GetStream.EndRead(ar)
End SyncLock
If intCount < 1 Then
RaiseEvent Disconnected(Me)
m_State = 0
Exit Sub
End If
' Create a string from the byte array of data received by the
' objclient.GetStream
BuildString(arData, 0, intCount)
' Restart the background listening for incoming data
SyncLock objClient.GetStream
objClient.GetStream.BeginRead(arData, 0, 1024, AddressOf Receive, Nothing)
End SyncLock
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
RaiseEvent Disconnected(Me)
m_State = 0
End Try
End Sub
Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
Dim intIndex As Integer
Dim txt As String
Console.Writeline("BuildString")
m_State = 2
objText = New StringBuilder()
' Loop through the Byte array byte by byte and turn it into a unicode
' string
For intIndex = offset To offset + count - 1
txt = ChrW(Bytes(intIndex))
objText.Append(txt)
Next
RaiseEvent DataReceived(Me, objText.ToString, objText.Length)
m_State = 1
End Sub
Public ReadOnly Property requestID() As String
' A connections requestID to identify it.
' This property returns a Guid. Use this to identify a specific
' client when using as as multi-connection server. You can
' store the class reference into a collection or hashtable
' and use the requestID as the unique key.
Get
Return m_requestID.ToString
End Get
End Property
Public ReadOnly Property ClientIP() As String
' The ip address of the connected client
Get
Return m_ClientIP
End Get
End Property
Public ReadOnly Property State() As Short
' The ip address of the connected client
' Possible values:
' 0 - Disconnected
' 1 - Connected And Ready
' 2 - Receiving
' 3 - Sending
' 4 - Connecting
Get
Return m_State
End Get
End Property
Public Sub Connect(ByVal strDomain As String, ByVal intPort As Integer)
m_State = 4
Try
' Start a new client passing the ip and port
objClient = New TcpClient(strDomain, intPort)
RaiseEvent Connected(Me)
m_State = 1
' Max data buffer size
objClient.ReceiveBufferSize = 1024
objClient.NoDelay = True
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
m_State = 0
End Try
End Sub
End Class
End Namespace
End Namespace
-
Mar 21st, 2002, 02:16 PM
#6
Frenzied Member
Thanks , I'll test this out later when I get home today.
Dont gain the world and lose your soul
-
Mar 24th, 2002, 07:58 PM
#7
Junior Member
only error
objClient.Send(Encoding.ASCII.GetBytes(Data))
is at objclient.send
-
Mar 25th, 2002, 09:43 AM
#8
this is starnge...eveyone is getting this compile error except me. 
i gotta figure out what is wrong..
-
Mar 25th, 2002, 10:05 AM
#9
ARRGHH! Then it stopped working on my machine..That makes no sense as it was working as is on my machine...Oh well...anyway..I rewrote the sending again. It is working again..hope it stays that way..
Code:
' Thanks goes out to my hommies at www.vbforums.com!
' Special Thanks To:
' JpEgy for fixing many minor mistakes and being the first tester.
' This file written with TextPad... Who needs Visual Studio?
Option Explicit
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.IO
Imports Microsoft.VisualBasic
Namespace Sockets
' All socket connection types
Namespace TCP
Public Class TCPConnection
' For TCP connections intercepted by the TcpListener
Private tcpConn As TcpClient
Private m_requestID As Guid = Guid.NewGuid
Private objClient As TcpClient
Private arData(1024) As Byte
Private m_ClientIP As String
Private m_State As Short
Private objText As New StringBuilder()
Private objWriter As BinaryWriter
Public Event Connected(ByVal sender As TCPConnection)
Public Event Disconnected(ByVal sender As TCPConnection)
Public Event DataReceived(ByVal sender As TCPConnection, ByVal Data As String, ByVal BytesReceived As Long)
Public Event SockError(ByVal strMessage As String)
Public Sub New(ByVal client As TcpClient)
' A new instance of the class started meaning a new connection
' New is a constructor that it called when New is used with creating
' A class instance
objClient = client
'RaiseEvent Connected(Me)
'Console.Writeline("Test")
m_State = 1
' Have the TcpClient object listen in the background for incoming
' data and call the Receive sub whenit does.
objClient.GetStream.BeginRead(arData, 0, 1024, _
AddressOf Receive, Nothing)
End Sub
Public Sub SendData(ByVal Data As String)
' Server sending to client. String Data
m_State = 3
' Send the string of Data to the client
'objClient.SendDataToClient(Encoding.ASCII.GetBytes(Data))
'Dim sendbyteData() As Byte = byteData
objWriter = New BinaryWriter(objClient.GetStream)
Try
objWriter.Write(Encoding.ASCII.GetBytes(Data), 0, Data.Length)
objWriter.Flush()
Catch e As Exception
Console.Writeline(e.Message.ToString)
End Try
m_State = 1
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
' Start the data receiving process
Dim intCount As Integer
Console.Writeline("Received")
Try
' check for an error while receiving data
SyncLock objClient.GetStream
intCount = objClient.GetStream.EndRead(ar)
End SyncLock
If intCount < 1 Then
RaiseEvent Disconnected(Me)
m_State = 0
Exit Sub
End If
' Create a string from the byte array of data received by the
' objclient.GetStream
BuildString(arData, 0, intCount)
' Restart the background listening for incoming data
SyncLock objClient.GetStream
objClient.GetStream.BeginRead(arData, 0, 1024, AddressOf Receive, Nothing)
End SyncLock
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
RaiseEvent Disconnected(Me)
m_State = 0
End Try
End Sub
Private Sub BuildString(ByVal Bytes() As Byte, ByVal offset As Integer, ByVal count As Integer)
Dim intIndex As Integer
Dim txt As String
Console.Writeline("BuildString")
m_State = 2
objText = New StringBuilder()
' Loop through the Byte array byte by byte and turn it into a unicode
' string
For intIndex = offset To offset + count - 1
txt = ChrW(Bytes(intIndex))
objText.Append(txt)
Next
RaiseEvent DataReceived(Me, objText.ToString, objText.Length)
m_State = 1
End Sub
Public ReadOnly Property requestID() As String
' A connections requestID to identify it.
' This property returns a Guid. Use this to identify a specific
' client when using as as multi-connection server. You can
' store the class reference into a collection or hashtable
' and use the requestID as the unique key.
Get
Return m_requestID.ToString
End Get
End Property
Public ReadOnly Property ClientIP() As String
' The ip address of the connected client
Get
Return m_ClientIP
End Get
End Property
Public ReadOnly Property State() As Short
' The ip address of the connected client
' Possible values:
' 0 - Disconnected
' 1 - Connected And Ready
' 2 - Receiving
' 3 - Sending
' 4 - Connecting
Get
Return m_State
End Get
End Property
Public Sub Connect(ByVal strDomain As String, ByVal intPort As Integer)
m_State = 4
Try
' Start a new client passing the ip and port
objClient = New TcpClient(strDomain, intPort)
RaiseEvent Connected(Me)
m_State = 1
' Max data buffer size
objClient.ReceiveBufferSize = 1024
objClient.NoDelay = True
Catch e As Exception
RaiseEvent SockError(e.Message.ToString)
m_State = 0
End Try
End Sub
End Class
End Namespace
End Namespace
-
Mar 25th, 2002, 10:20 PM
#10
Junior Member
question
goin thru all this.. but where does it specificy what port to listen on?
thanks
-
Mar 26th, 2002, 07:45 AM
#11
Frenzied Member
VB Code:
Public Sub Connect(ByVal strDomain As String, ByVal intPort As Integer)
so it would be connect("mydomain.com", MyPortNumber)
Jop - validweb.nl
Alcohol doesn't solve any problems, but then again, neither does milk.
-
Mar 26th, 2002, 08:55 AM
#12
Junior Member
great
hm.. ok you can connect with that.. but bare with me for a second... have never messed with tcp/ip..(btw.. what's a good book to read to learn it?) i can connect.. but how do i make a server listen on a certain port for incoming connections...
karthic
-
Mar 26th, 2002, 09:21 AM
#13
sorry guess i should include the server usage example. This class does not do the listenting. You need to add a TcPListener class which is where the port is specified..here is a sample app showing how to listen for multiple connections on port 2500, store the clients into a hashtable(aka collection) and send data to all clients connected
Code:
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports Sockets.TCP
Imports System.Threading
Imports System.Collections
Module App1
Private mobjListener As TcpListener
Private WithEvents x As TCPConnection
Private thdListen As Thread
Private colClients As New Hashtable()
Sub Main()
Console.WriteLine("Server Started")
thdListen = New Thread(AddressOf DoListen)
thdListen.Start()
End Sub
Private Sub DoListen()
Try
' Start the listening Socket on port 2500
mobjListener = New TcpListener(2500)
mobjListener.Start()
Do
x = New TCPConnection(mobjListener.AcceptTcpClient)
AddHandler x.DataReceived, AddressOf OnDataReceived
Console.Writeline("New Connection Received")
AddHandler x.Connected, AddressOf Connection
' Add class reference to a hashtable for later reference. Make the
' requestID the unique key.
colClients.Add(x.requestID, x)
Loop Until False
Catch
End Try
End Sub
Private Sub OnDataReceived(ByVal sender As TCPConnection, ByVal Data As String, ByVal Bytes As Long)
Console.Writeline("in: " & Data)
Console.Writeline("id: " & sender.requestID)
Console.Writeline("bytes: " & Bytes)
Dim y As DictionaryEntry
Dim a As TCPConnection
For Each y In colClients
' Set a to the value of the current class from the hashtable
a = y.Value
Console.Writeline(a.requestID)
a.SendData(Data)
Next y
End Sub
Sub Connection(ByVal sender As TCPConnection)
Console.WriteLine("Connection")
End Sub
End Module
-
Mar 28th, 2002, 09:05 PM
#14
Junior Member
excuse me while i',m still learning
Code:
Dim asdf As Sockets.TCP.TCPConnection
asdf.Connect("mydomain.com", 23)
compiles with the error
Code:
Additional information: Object reference not set to an instance of an object.
what does that error mean?
hmm
thanks
karthic
-
Mar 28th, 2002, 11:47 PM
#15
Junior Member
still cant figure out
how to run the sub's in that namespace.. just cant do it..
hmmm
gezz
help?
-
Mar 29th, 2002, 06:37 PM
#16
Frenzied Member
Not sure in this case... but you can try:
VB Code:
Dim asdf As [b]New[/b] Sockets.TCP.TCPConnection
Good luck
Jop - validweb.nl
Alcohol doesn't solve any problems, but then again, neither does milk.
-
Apr 2nd, 2002, 12:14 AM
#17
Junior Member
ok.. last question on this topic
i promise.. sure.. sure.. 
how do i send binary data, like mp3 files from this to a client.. for it to recieve and store to a file... i just cant figgure that out..
thanks
karthic
-
Sep 30th, 2002, 09:19 AM
#18
Use the Disconnected event.
-
Oct 2nd, 2002, 08:30 AM
#19
Did you add the class to the project?
-
Oct 2nd, 2002, 03:21 PM
#20
Can you serialize objects to the network stream? I am using basically this class but instead of writing the string to the stream with the streamwriter I am serializing a Message object but I keep getting out of memory errors.
-
Oct 15th, 2002, 02:53 AM
#21
Member
Any idea what'd be causing this?
Was working great, then I tried to get it handling each connection in a separate thread (I don't think that's what it's doing at the moment, anyway), and Bad Things started happening. Specifically:
Code:
Unable to read data from the transport connection.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at TCPConnection.Receive(IAsyncResult ar) in TCPConnection.vb:line 69
My DoListen() function (based on the function used in the original thread):
VB Code:
Private Sub DoListen()
mobjListener = New Net.Sockets.TcpListener(27753)
mobjListener.Start()
Do
Dim x As New TCPConnection(mobjListener.AcceptTcpClient)
Dim myThread As Threading.Thread = New Threading.Thread(AddressOf x.Go)
AddHandler x.DataReceived, AddressOf OnDataReceived
AddHandler x.OnDisconnect, AddressOf myThread.Abort
myThread.Start()
Loop Until False
End Sub
And to get that working, I split the New() function into the following:
VB Code:
Public Sub New(ByVal client As TcpClient)
' A new instance of the class started meaning a new connection
' New is a constructor that it called when New is used with creating
' A class instance
objClient = client
End Sub
Public Sub Go()
RaiseEvent Connected(Me)
m_State = 1
' Have the TcpClient object listen in the background for incoming
' data and call the Receive sub whenit does.
objClient.GetStream.BeginRead(arData, 0, 1024, AddressOf Receive, Nothing)
End Sub
Matthew Draper
[email protected]
"Genius may have its limitations, but stupidity is not thus handicapped." - Elbert Hubbard
"I like long walks, especially when they are taken by people who annoy me." - Noel Coward
-
Nov 23rd, 2002, 06:07 PM
#22
Addicted Member
Could you please post an example on client usage (threaded)?
Thanks.
-
Sep 23rd, 2003, 03:25 AM
#23
Member
Can someone re code the server part? I can't seem to get it to work.
-
Jan 25th, 2006, 09:29 AM
#24
New Member
Re: JpEgy - Working TCP class!!
Hi all .
I need a full sample for tranasfer file between 2 pc on the network with VB.NET2005 .
does anyone have a client/server application to get me .?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|