Thread Pooled Socket handling

Aia

Member
Joined
Oct 9, 2007
Messages
21
Location
Canada
Programming Experience
Beginner
I am very new to working with sockets so I have no idea if anything I am doing is correct.
I am working on a program that has a thread pool to deal with when something connects to a socket. I run into the problem of not being able to tell when the client has disconnected unless I intentionally create an error that occurs by trying to send something. I am not allowed to close the socket myself, the socket must be kept open so that more then a single packet can be sent. There is no set amount of packets either. I must keep the thread alive until the one who requested the socket disconnects.


Here is my code that is revalent. If you need something I failed to provide just tell me what and I will post it as soon as possible.

VB.NET:
Imports System.Net.Sockets
Imports System.net
Imports System.Text
Imports System.Threading

    Dim portnumber As Integer = xxxx 'Incoming Port from Units
    Dim MainSocketThread As New System.Threading.Thread(AddressOf SocketThread)
    Dim sendport As Integer = xxxx 
    Dim something As New SocketException
    Dim something2 As New SocketError
    Dim asdf As Socket

Public Sub SocketThread()
        Try
            Dim sockettcpListener As New TcpListener(CType(Dns.GetHostEntry("xxx.xxx.xxx.xxx").AddressList(0), IPAddress), portnumber)
            sockettcpListener.Start()
            Try
                Dim i As Integer = 0
                While i < 1
                    Dim sockettcpClient As TcpClient = sockettcpListener.AcceptTcpClient()
                    ThreadPool.QueueUserWorkItem(AddressOf listenthread, sockettcpClient)
                End While
            Catch ex As Exception
                MessageBox.Show("Thread stopped running at " & System.DateTime.Now & vbNewLine & ex.Message)
            End Try
            sockettcpListener.Stop()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
    Public Sub listenthread(ByVal sockettcpClient)
        Debug.WriteLine("start Socket thread id: " & System.Threading.Thread.CurrentThread.ManagedThreadId)
        Try
            Do

                Dim networkStream As NetworkStream = sockettcpClient.GetStream()
                Dim bytes(sockettcpClient.ReceiveBufferSize) As Byte
                networkStream.Read(bytes, 0, CInt(sockettcpClient.ReceiveBufferSize))
                parsed(bytes)
                'networkStream.WriteByte(142) 'hex code "8E"
'This line is the inserted error line.

                            Loop While (socket is open)
        Catch ex As Sockets.SocketException

            Debug.WriteLine(ex.ErrorCode.ToString)

        Catch ex As IO.IOException
            Debug.WriteLine("io error " & ex.Message)
            Debug.WriteLine(something.ErrorCode.ToString)
                Select Case something.ErrorCode
                Case 0
                    Debug.WriteLine("success")
                Case Sockets.SocketError.Success

                Case Else
                    Debug.WriteLine("diff message: " & something.ErrorCode)
            End Select
        Catch ex As Exception

            Debug.WriteLine(System.DateTime.Now & "   " & "Socket listen error: " & ex.ToString)
            Debug.WriteLine("something's text " & something.ErrorCode.ToString())
        End Try
        Debug.WriteLine("end Socket thread id: " & System.Threading.Thread.CurrentThread.ManagedThreadId)
    End Sub
    


    Public Sub parsed(ByVal bytes)
        Debug.WriteLine("Extracted: " & byterun(bytes, 0, bytes.ToString.Length))
           End Sub
 
Last edited by a moderator:
Check return value of Read function, it return actual number of bytes read of what you requested, or 0 if client disconnects cleanly.
 
Thank you for the reply. I changed the code inside the loop to the following and tested it and it works the way I need it to. Thank you for helping me figure it out.



Do
Dim networkStream As NetworkStream = sockettcpClient.GetStream()
Dim bytes(sockettcpClient.ReceiveBufferSize) As Byte
networkStream.Read(bytes, 0, CInt(sockettcpClient.ReceiveBufferSize))
If (bytes(0) = 0) Then
Exit Do
Else
'parsed(bytes)
Debug.WriteLine("parsed function")
End If
Loop While True
 
You can't use bytes(0) to check the return value of the function call.
dim NumberOfBytesActuallyRead as integer = s.Read(...)
 
I have changed the code so that it now looks like this.

If (networkStream.Read(bytes, 0, CInt(sockettcpClient.ReceiveBufferSize)) = 0) Then
Exit Do

Is that correct way for doing it?
 
No, because if it return other than 0 you need to know that number, it will tell you which part of the buffer array that has been filled.
 
Then why does the code still work with multiple packets? The code behaves the way I want it too, but from what you are saying its not behaving the correct way.
 
Well, that's functionality of the Read function, that's how it works. I have no idea what you do with your received data, perhaps all zero bytes is insignification to your later processing?
 
So the read function is able to return several numbers based on what happens. So a select case on that would work better then the if. Would you be able to give me some pointers to some articles I can read so I can understand this function better? I also want to thank you for your help in this. It is proving most useful.
 
It all documented... here the online page NetworkStream.Read Method but you'll get much better performance by reader your local help. You wouldn't use a select case, you would get the returned value and check if it's 0, which means disconnect, else you handle the part of the array designated by the value. For example you have declared a buffer array the size of ReceiveBufferSize, lets say this is 8192 bytes, and you request this number of bytes with the Read function, in many cases you are returned a smaller number of bytes, for example 123. The rest of your buffer array now contains 0 value bytes if the array is fresh/initialized, or if you used the same buffer for last request it will still contain the remaining of that, but that really doesn't matter since you know exactly what was given you by the last read.

I also must mention that in many socket cases you don't operate with bytes at all, stream readers are used often, so is serialization, both these methods will read the content that is expected even if it spawn only part of one receive buffer or also several buffers.
 
Back
Top