Newbie lost in socket programming with error "An existing connection was forcibly closed by the remote host"

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



Answer this question

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.NetworkStream

    ServerSocket.Blocking = True

    ClientSocket.Blocking = True

    ServerSocket.Bind(LocalIPEndPoint)

    ServerSocket.Listen(10)

    Do

    AcceptSocket = 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) Then

    C_NetStream.Read(C_Bytes, 0, C_Bytes.Length)

    S_NetStream.Write(C_Bytes, 0, C_Bytes.Length)

    End If

    End While

    System.Threading.Thread.Sleep(50)

    End While

    End If

    C_NetStream.Close()

    C_NetStream.Dispose()

    S_NetStream.Close()

    S_NetStream.Dispose()

    ClientSocket.Close()

    Loop


  • Derek 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 = True

    ServerSocket.Bind(LocalIPEndPoint)

    ServerSocket.Listen(10)

    Do

    AcceptSocket = 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) Then

    C_NetStream.Read(C_Bytes, 0, C_Bytes.Length)

    S_NetStream.Write(C_Bytes, 0, C_Bytes.Length)

    End If

    End While

    System.Threading.Thread.Sleep(50)

    End While

    End If

    C_NetStream.Close()

    C_NetStream.Dispose()

    S_NetStream.Close()

    S_NetStream.Dispose()

    ClientSocket.Close()

    Loop


  • SeveQ

    hi ,
    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 String

    ServerSocket = 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 = 0

    ClientSocket = New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)

    AcceptSocket = ServerSocket.Accept()

    'AcceptSocket.Blocking = False

    ClientSocket.Connect(RemoteHost, RemotePort)

    If (Not ClientSocket.Connected) Then

    MsgBox("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 While

    System.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 If

    ClientSocket.Shutdown(Net.Sockets.SocketShutdown.Both)

    ClientSocket.Disconnect(True)

    AcceptSocket.Shutdown(Net.Sockets.SocketShutdown.Both)

    AcceptSocket.Disconnect(True)

    Loop


  • Adam 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 0Then
                        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 0Then
                        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.NetworkStream

    ServerSocket.Blocking = True

    ClientSocket.Blocking = True

    ServerSocket.Bind(LocalIPEndPoint)

    ServerSocket.Listen(10)

    Do

    AcceptSocket = 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 anymore

    Bytes = new Byte(4096) {}

    S_NetStream.Read(Bytes, 0, Bytes.Length)

    C_NetStream.Write(Bytes, 0, Bytes.Length)

    If (C_NetStream.DataAvailable = True) Then

    Bytes = new Byte(4096) {}

    C_NetStream.Read(Bytes, 0, Bytes.Length)

    S_NetStream.Write(Bytes, 0, Bytes.Length)

    End If

    End While

    System.Threading.Thread.Sleep(50)

    End While

    End If

    C_NetStream.Close()

    C_NetStream.Dispose()

    S_NetStream.Close()

    S_NetStream.Dispose()

    ClientSocket.Close()

    Loop


  • Ant&amp;#243;nio Jo&amp;#227;o Carri&amp;#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

     


  • Newbie lost in socket programming with error "An existing connection was forcibly closed by the remote host"