Hello,
I'm trying to develop a tcp/ip request forwarder using system.net.sockets and VB 2005
I read somewhere not to use TcpClient and TcpServer for performance concerns... So I've been trying for 2 days without any success with following code.
Any help would be really appreciated
Dim theIPEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 81)
Dim ServerSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim ClientSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim aSocket As System.Net.Sockets.Socket
ServerSocket.Blocking = True
ServerSocket.Bind(theIPEndPoint)
ServerSocket.Listen(10)
Dim SBuffer(4096) As [Byte], CBuffer(4096) As [Byte]
Dim SPack As String = "", CPack As String = ""
Dim SBytes As Integer, CBytes As Integer
aSocket = ServerSocket.Accept()
ClientSocket.Connect("192.168.1.1", 80)
If (ClientSocket.Connected = True) Then
While (aSocket.Connected = True)
Do
SBytes = aSocket.Receive(SBuffer) 'This is the LINE IN ERROR OR APPLICATION FREEZE POINT
SPack = SPack & System.Text.Encoding.Default.GetString(SBuffer)
Loop While (SBytes <> 0)
Do
CBytes = CBytes + ClientSocket.Send(System.Text.Encoding.Default.GetBytes(SPack))
Loop While (CBytes < SPack.Length)
Do
CBytes = ClientSocket.Receive(CBuffer)
CPack = CPack & System.Text.Encoding.Default.GetString(CBuffer)
Loop While (CBytes <> 0)
SBytes = 0
Do
SBytes = SBytes + aSocket.Send(System.Text.Encoding.Default.GetBytes(CPack))
Loop While (SBytes < CPack.Length)
End While
aSocket.Close()
End If

Newbie lost in socket programming with error "An existing connection was forcibly closed by the remote host"
Birkbaum
I've been trying this code today... Unsuccessful as well
Dim ServerSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp) Dim ClientSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp) Dim LocalIPEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 81) Dim S_Bytes(4096) As [Byte] Dim C_Bytes(4096) As [Byte] Dim AcceptSocket As System.Net.Sockets.Socket Dim S_NetStream As System.Net.Sockets.NetworkStream, C_NetStream As System.Net.Sockets.NetworkStreamServerSocket.Blocking =
TrueClientSocket.Blocking =
TrueServerSocket.Bind(LocalIPEndPoint)
ServerSocket.Listen(10)
DoAcceptSocket = ServerSocket.Accept()
S_NetStream =
New System.Net.Sockets.NetworkStream(AcceptSocket, True)S_NetStream.ReadTimeout = 5000
S_NetStream.WriteTimeout = 5000
ClientSocket.Connect(
"192.168.1.1", 80)C_NetStream =
New System.Net.Sockets.NetworkStream(ClientSocket)C_NetStream.ReadTimeout = 5000
C_NetStream.WriteTimeout = 5000
If (ClientSocket.Connected = True) Then While ((AcceptSocket.Connected = True) And (ClientSocket.Connected = True)) While (S_NetStream.DataAvailable = True)S_NetStream.Read(S_Bytes, 0, S_Bytes.Length)
C_NetStream.Write(S_Bytes, 0, S_Bytes.Length)
If (C_NetStream.DataAvailable = True) ThenC_NetStream.Read(C_Bytes, 0, C_Bytes.Length)
S_NetStream.Write(C_Bytes, 0, C_Bytes.Length)
End If End WhileSystem.Threading.Thread.Sleep(50)
End While End IfC_NetStream.Close()
C_NetStream.Dispose()
S_NetStream.Close()
S_NetStream.Dispose()
ClientSocket.Close()
LoopDerek Chan
Hi,
Indeed, I forgot to highlight where the error occurs... Sorry
Actually, there is definitelly no error message... For what matters the [Byte], I copied it from Microsoft Sample code; it looks to be the same as you defined above (as Byte {})
Cheers
Dim ServerSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim ClientSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim LocalIPEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 81)
Dim S_Bytes(4096) As [Byte]
Dim C_Bytes(4096) As [Byte]
Dim AcceptSocket As System.Net.Sockets.Socket
Dim S_NetStream As System.Net.Sockets.NetworkStream, C_NetStream As System.Net.Sockets.NetworkStream
ServerSocket.Blocking = True
ClientSocket.Blocking =
TrueServerSocket.Bind(LocalIPEndPoint)
ServerSocket.Listen(10)
DoAcceptSocket = ServerSocket.Accept()
S_NetStream =
New System.Net.Sockets.NetworkStream(AcceptSocket, True)S_NetStream.ReadTimeout = 5000
S_NetStream.WriteTimeout = 5000
ClientSocket.Connect(
"192.168.1.1", 80)C_NetStream =
New System.Net.Sockets.NetworkStream(ClientSocket)C_NetStream.ReadTimeout = 5000
C_NetStream.WriteTimeout = 5000
If (ClientSocket.Connected = True) Then While ((AcceptSocket.Connected = True) And (ClientSocket.Connected = True)) While (S_NetStream.DataAvailable = True)S_NetStream.Read(S_Bytes, 0, S_Bytes.Length) => On first, everything is perfect and the browser is well receiving data but on second loop the Listener freezes
C_NetStream.Write(S_Bytes, 0, S_Bytes.Length)
If (C_NetStream.DataAvailable = True) ThenC_NetStream.Read(C_Bytes, 0, C_Bytes.Length)
S_NetStream.Write(C_Bytes, 0, C_Bytes.Length)
End If End WhileSystem.Threading.Thread.Sleep(50)
End While End IfC_NetStream.Close()
C_NetStream.Dispose()
S_NetStream.Close()
S_NetStream.Dispose()
ClientSocket.Close()
LoopSeveQ
loooool i asked you wich line your program doesn't response and you never mentioned this, but you said in first loop its ok but in second loop your program die
advind
Hi,
I've got the impression I'm getting silly
The code below is running (most of the time) BUT depending on the sleep time ( ). If no sleep time, the browser doesn't receive anything, sleep time to 250 milliseconds and it is OK...
Private Const SleepTime As Long = 0 Private Const RemoteHost As String = "192.168.1.110" Private Const RemotePort As Integer = 80 Dim ServerSocket As System.Net.Sockets.Socket Dim LocalIPEndPoint As System.Net.IPEndPoint Dim ClientSocket As System.Net.Sockets.Socket Dim Bytes() As Byte Dim AcceptSocket As System.Net.Sockets.Socket Dim Decoded As StringServerSocket =
New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)LocalIPEndPoint =
New System.Net.IPEndPoint(System.Net.IPAddress.Any, 81)ServerSocket.Bind(LocalIPEndPoint)
ServerSocket.Listen(1000)
Me.Text = "Listening on " & ServerSocket.LocalEndPoint.ToString & "..." Me.Refresh() Do Dim TransBytes As Integer = 0ClientSocket =
New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)AcceptSocket = ServerSocket.Accept()
'AcceptSocket.Blocking = FalseClientSocket.Connect(RemoteHost, RemotePort)
If (Not ClientSocket.Connected) ThenMsgBox(
"Client socket failure !", MsgBoxStyle.Critical) End If If (ClientSocket.Connected = True) Then 'ClientSocket.Blocking = False While ((AcceptSocket.Connected = True) And (ClientSocket.Connected = True)) If ((AcceptSocket.Available = 0) And (ClientSocket.Available = 0)) Then Exit While End If While (AcceptSocket.Available > 0)Bytes =
New Byte(AcceptSocket.Available) {}TransBytes = AcceptSocket.Receive(Bytes)
ClientSocket.Send(Bytes)
Decoded = System.Text.Encoding.Default.GetString(Bytes)
Debug.Print(
"----------S Packet_0:" & vbCrLf & Decoded & vbCrLf & "----------" & vbCrLf)System.Threading.Thread.Sleep(SleepTime)
Erase Bytes End WhileSystem.Threading.Thread.Sleep(SleepTime)
While (ClientSocket.Available > 0)Bytes =
New Byte(ClientSocket.Available) {}TransBytes = ClientSocket.Receive(Bytes)
AcceptSocket.Send(Bytes)
Decoded = System.Text.Encoding.Default.GetString(Bytes)
Debug.Print(
"----------C Packet_0:" & vbCrLf & Decoded & vbCrLf & "----------" & vbCrLf)System.Threading.Thread.Sleep(SleepTime)
Erase Bytes End While End While End IfClientSocket.Shutdown(Net.Sockets.SocketShutdown.Both)
ClientSocket.Disconnect(
True)AcceptSocket.Shutdown(Net.Sockets.SocketShutdown.Both)
AcceptSocket.Disconnect(
True) LoopAdam Mishler
hi,
i guess this is the reason
you wrote something strange to me Dim SBuffer(4096) As [Byte], CBuffer(4096) As [Byte]
what is this [byte] anyway you have to declare it and in each loop you have to reconstract the byte array or it will give you a headache
Dim SBuffer As Byte()While (aSocket.Connected = True)Do
SBuffer = New Byte(1024) {}
SBytes = aSocket.Receive(sBuffer, 0, sBuffer.Length, Net.Sockets.SocketFlags.None)
hope this helps
CSharpner
hi,
sure because sockets are blocking by default i don't think you should declare that either because its default value
more over the sockets.read returns values represent the number of bytes recieved you can use this
here its an echo server program that i has it accept a text message then send it back to the client as its (you can change this part to send it to particular server) then it convert the bytes to string for console to writeLine("you don't need this part")
Namespace NetWorkingServers
Imports System.Net
Imports System.Text
Imports System.Net.Sockets
Imports System.Threading
Class E1_ThreadedTCPServer
Private srvr As TcpListener
Public Sub New()
MyBase.New
srvr = New TcpListener(1234)
srvr.Start
Console.WriteLine("Waiting for Clients ...")
While true
'keep looping till the server recieve request for connection
While Not srvr.Pending
Thread.Sleep(1000)
End While
'creat instance of the other class
Dim newconnection As connectionThread = New connectionThread
newconnection.threadListener = Me.srvr
Dim newthread As Thread = New Thread(New ThreadStart(newconnection.HandleConnection))
newthread.Start
End While
End Sub
End Class
'E1_threadedServer
Class connectionThread
Public threadListener As TcpListener
Private Shared connections As Integer = 0
Public Sub HandleConnection()
Dim recv As Integer
Dim data() As Byte = New Byte(1024) {}
Dim client As TcpClient = threadListener.AcceptTcpClient
Dim ns As NetworkStream = client.GetStream
connections += 1
Console.WriteLine("New client Accepted: {0} Active connections", connections)
'send welcome message
Dim strdata As String = "Welcome to my Threaded Server"
data = Encoding.UTF8.GetBytes(strdata)
ns.Write(data, 0, data.Length)
' send and recieve
While true
data = New Byte(1024) {}
recv = ns.Read(data, 0, data.Length)
'if client is no more active kill this connection
If (recv = 0) Then
Exit while
End If
strdata = Encoding.UTF8.GetString(data, 0, recv)
Console.WriteLine(strdata)
ns.Write(data, 0, recv)
End While
'close every thing
connections = (connections - 1)
Console.WriteLine("Client Disconnected : {0} Active Connections", connections)
ns.Close
client.Close
'ToDo : Aport thread
End Sub
End Class
End Namespace
hope this helps
JPulham
hi,
i use this part to check if the client closed hte connection
While true
'if client is no more active kill this connection
If (recv = 0) Then
Exit while
End If
'ToDO : recieve of send data
End While
i think when tcp close connection is it send a close packet which dosn't contain any data so if the data in the packet = 0 then its closing connection packet
i use this and it works,
one more thing your code will give you a headache if it worked you will find the messages will appear in the textbox in funny way
no way to gurantee the message will be recieved as you send it with tcp, and the array will initiate all elments so if you program recieved hello it will read it ("hello 'space' * 4029" ) the space will be repeated as much as the array elements so you have to manuplate it during encoding like this System.Text.Encoding.Default.GetString(Data,0, recv) or you will get all those white spaces
you can use string.trim but this is wast of time why you have to read it and then trim it , just read the avilable data
hope this helps
erivas
hi,
first of all when you use TCP\IP there is no gurantee that the data will be delivered as you expected
so to use TCP\ip you should send the packet length something like a header for your packet or 2 separated packet or as you like
or as alternative for that to use delemited packets like streamreader or stream writer if its text messages because it will be delemited by new line or you can design your own delemiter
one more thing is to redeclair your array b4 every read or it will give you a headache as i told you
2 days or even 2 months is not long while to learn sockets because its the most tricky thing i saw in .net
there is a forum for networking http://forums.microsoft.com/MSDN/ShowForum.aspx ForumID=40&SiteID=1
if you want this thread to be moved there tell me
hope this helps
PavanE
Hi,
Many thanks for your help again. What I think I've understood so far is that the "Connected" does not really handle if the socket is connected or not; I mean if the remote host disconnects, the "Connected" property of whatever else is not updated within the .Net socket handler...
Here is a code I tried to translate from a java application which is working properly to VB.NET; I think this should work but (see below in red in the code): I've testing both java and VB.Net apps with a sniffer in order to check what is really happening
owangecounty
Hi,
No problem for me to move in a more appropriate forum...
The problem is that the application doesn't know what it will receive in advance: it can be structured with header as it cannot...
I'm currently trying to build the application as a relay beteween Internet Explorer and a Web Server.
Here is the code of my today's test:
Dim ServerSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim ClientSocket As System.Net.Sockets.Socket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
Dim LocalIPEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 81)
Dim Bytes() As Byte
Dim AcceptSocket As System.Net.Sockets.Socket Dim S_NetStream As System.Net.Sockets.NetworkStream, C_NetStream As System.Net.Sockets.NetworkStreamServerSocket.Blocking =
TrueClientSocket.Blocking =
TrueServerSocket.Bind(LocalIPEndPoint)
ServerSocket.Listen(10)
DoAcceptSocket = ServerSocket.Accept()
S_NetStream =
New System.Net.Sockets.NetworkStream(AcceptSocket, True)S_NetStream.ReadTimeout = 5000
S_NetStream.WriteTimeout = 5000
ClientSocket.Connect(
"192.168.1.1", 80)C_NetStream =
New System.Net.Sockets.NetworkStream(ClientSocket)C_NetStream.ReadTimeout = 5000
C_NetStream.WriteTimeout = 5000
If (ClientSocket.Connected = True) Then While ((AcceptSocket.Connected = True) And (ClientSocket.Connected = True)) While (S_NetStream.DataAvailable = True) ON FIRST LOOP It is OK but in second loop it is not because there is no data anymoreBytes = new Byte(4096) {}
S_NetStream.Read(Bytes, 0, Bytes.Length)
C_NetStream.Write(Bytes, 0, Bytes.Length)
If (C_NetStream.DataAvailable = True) ThenBytes = new Byte(4096) {}
C_NetStream.Read(Bytes, 0, Bytes.Length)
S_NetStream.Write(Bytes, 0, Bytes.Length)
End If End WhileSystem.Threading.Thread.Sleep(50)
End While End IfC_NetStream.Close()
C_NetStream.Dispose()
S_NetStream.Close()
S_NetStream.Dispose()
ClientSocket.Close()
LoopAnt&#243;nio Jo&#227;o Carri&#231;o
hi,
ok make a break point and step over your code, and post the error message if there any or where does the application freez , one which line
i still don't know why you put brackets around the array type "[byte]"
best regards
Moonracer
Hi,
Thanks for your help. I changed the code as you suggested.
Now, the app does not return the error anymore but freezes in the first do/loop section after the second loop on SBytes = aSocket.Receive(sBuffer, 0, sBuffer.Length, Net.Sockets.SocketFlags.None)...
It looks that aSocket.Receive does not return zero