Socket nightmare 
Author Message
 Socket nightmare

Thanks for the people that answered my question before, but I ended up
redoing it all with sockets instead of a tcplistener. Anyway I have spent
the last 2 weeks working on this and it is driving me insane. Sorry I
don't have anyone else to turn to so I hope you guys can be helpful ^.^;

Anyway the listener class seems to work fine, it accepts connections and
everything nicely. Occasionally I get the first line of stuff sent from
the client, but otherwise both the sending and receiving of the socket
stream die after that. I can't read anything from it nor send anything at
all. Anyways, as I have said I've been working on this a very long time
and cant figure it out. Thanks for reading this everyone ^.^ The whole
darn namespace follows:

Option Explicit On
Option Strict On

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.Collections

Namespace GsSockets
#Region " Deligates "
    Public Delegate Sub DataArrivalDelegate(ByVal RequestID As Integer,
ByVal Data As String)
    Public Delegate Sub DisconnectedDelegate(ByVal RequestID As Integer)
#End Region
    Public Class SocketServer
        Private sckListener As TcpListener
        Private trdListener As Thread
        Private objClientPool As ClientPool
        Private intListenPort As Integer

        ' Fired when a new client connects.
        Public Event ClientConnected(ByVal RequestID As Integer)
        Public Event DataArrival As DataArrivalDelegate
        Public Event ClientDisconnected As DisconnectedDelegate

        Public Sub New()
        End Sub
        Public Sub Listen(ByVal ListenPort As Integer)
            intListenPort = ListenPort
            objClientPool = New ClientPool()
            trdListener = New Thread(AddressOf ListenThread)
            trdListener.Start()
        End Sub
        Private Sub ListenThread()
            Try
                sckListener = New TcpListener(intListenPort)
                sckListener.Start()
            Catch ex As Exception
                MsgBox("Listen Error")
                ' TODO: Error Handling
                Exit Sub
            End Try
            Do While True
                Dim sckClient As Socket = sckListener.AcceptSocket()
                If sckClient.Connected Then
                    Dim objConnectedSocket As New Client(sckClient)
                    objClientPool.Add(CType(sckClient.Handle.ToInt32,
Integer), objConnectedSocket)
                    AddHandler objConnectedSocket.DataArrival, AddressOf
DataArrivalMethod
                    AddHandler objConnectedSocket.ClientDisconnected,
AddressOf ClientDisconnectedMethod
                        RaiseEvent ClientConnected(CType
(sckClient.Handle.ToInt32, Integer))
                End If
            Loop
        End Sub
        Public Sub Close()
            sckListener.Stop()
            trdListener.Abort()
            Try
                objClientPool.Dispose()
            Catch
            End Try
        End Sub
        Public Sub Disconnect(ByVal RequestID As Integer)
            objClientPool.Remove(RequestID)
        End Sub
        Public Sub SendData(ByVal RequestID As Integer, ByVal Data As
String)
            objClientPool.SendData(RequestID, Data)
        End Sub
        Public Sub Broadcast(ByVal Data As String)
            objClientPool.Broadcast(Data)
        End Sub
        Private Sub DataArrivalMethod(ByVal RequestID As Integer, ByVal
Data As String)
            RaiseEvent DataArrival(RequestID, Data)
        End Sub
        Private Sub ClientDisconnectedMethod(ByVal RequestID As Integer)
            RaiseEvent ClientDisconnected(RequestID)
        End Sub
    End Class

    Public Class ClientPool
        Private ClientTable As New Hashtable()

        Public Sub Add(ByVal RequestID As Integer, ByVal Socket As
Client)
            Try
                ClientTable.Add(RequestID, Socket)
            Catch ex As Exception
                ' TODO: Error handling
            End Try
        End Sub
        Public Sub Remove(ByVal RequestID As Integer)
            Try
                Dim connectedSocket As Client = CType(ClientTable.Item
(RequestID), Client)
                connectedSocket.CloseSocket()
                ClientTable.Remove(RequestID)
            Catch ex As Exception
                ' TODO: Error Handling
            End Try
        End Sub
        Public Sub SendData(ByVal RequestID As Integer, ByVal Data As
String)
            Try
                Dim sckSocket As Client = CType(ClientTable.Item
(RequestID), Client)
                sckSocket.SendData(Data)
            Catch ex As Exception
                ' TODO: Error Handling
            End Try
        End Sub
        Public Sub Broadcast(ByVal Data As String)
            Dim objClient As Client
            Dim key As Integer

            Try
                For Each key In ClientTable.Keys
                    objClient = CType(ClientTable.Item(key), Client)
                    objClient.SendData(Data)
                Next
            Catch ex As Exception
                ' TODO: Error Handling
            End Try
        End Sub
        Public Sub Dispose()
            Dim key As Integer
            Try
                For Each key In ClientTable.Keys
                    Dim sckSocket As Client = CType(ClientTable.Item
(key), Client)
                    sckSocket.CloseSocket()
                Next
            Catch ex As Exception
                ' TODO: Error Handling
            End Try
        End Sub

    End Class

    Public Class Client
        Private trdClient As Thread
        Private sckClient As Socket
        Private readBuffer(32767) As Byte

        Public Event DataArrival As DataArrivalDelegate
        Public Event ClientDisconnected As DisconnectedDelegate

        Public Sub New(ByVal sckSocket As Socket)
            sckClient = sckSocket
            sckClient.BeginReceive(readBuffer, 0, 32767,
SocketFlags.None, AddressOf DataArrivalThread, Nothing)
        End Sub
        Public Sub SendData(ByVal Data As String)
            Dim byteData() As Byte
            byteData = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
            SyncLock sckClient
                sckClient.Send(byteData)
            End SyncLock
        End Sub
        Private Sub DataArrivalThread(ByVal ar As IAsyncResult)
            Dim intReadBytes As Integer
            Dim strData As String
            Try
                Do While True
                    SyncLock sckClient
                        ' Stop async read to get the data
                        intReadBytes = sckClient.EndReceive(ar)
                    End SyncLock

                    sckClient.Receive(readBuffer, 0, sckClient.Available,
SocketFlags.None)
                    strData = Encoding.ASCII.GetString(readBuffer, 0,
intReadBytes - 1)
                    RaiseEvent DataArrival(CType
(sckClient.Handle.ToInt32, Integer), strData)
                    SyncLock sckClient
                        ' Restart async read
                        sckClient.BeginReceive(readBuffer, 0, 32767,
SocketFlags.None, AddressOf DataArrivalThread, Nothing)
                    End SyncLock
                Loop
            Catch ex As Exception
                ' TODO: Error Handling
                CloseSocket()
            End Try
        End Sub
        Public Sub CloseSocket()
            RaiseEvent ClientDisconnected(CType(sckClient.Handle.ToInt32,
Integer))
            sckClient.Shutdown(SocketShutdown.Both)
            sckClient.Close()
        End Sub
    End Class
End Namespace



Sun, 24 Jul 2005 10:09:04 GMT  
 Socket nightmare
Gary:

What it sounds to me is you're not emptying the incoming buffer completely
before executing the next serialized command.

Suppose I created a connection to a nntp newsserver.

Once the connection is made, I get a return of either 200 or 201 assumming
the connection worked and the server responds.

Assumming that worked, I can then either tell the server I'm sending
something up its way or I want to find out what's new at, let's say, this
newsgroup.

So, I tell it to point my server connection to that folder.

It's going to come back with a response and tells me some information about
how many items are available as well as the high and low number.

All of this is all well and good...And I don't mean to bore you here..the
point is, suppose I make a request to the server for a specific news item.

There's going to be two packects sent.  One confirming the existance of the
item and the second sending the actual header, article or body information.

This is where I think you're having the problem. When one packet arrives,
there's no back and forth communications regarding the second.  It is sent
automatically.

But you're saying it worked before. I know I did see some changes -- for
example -- with the nntp protocol which was enough to cause me to change my
logic.

Anyway, its just a hunch.

Also, if you have the tcpip icon in the tray when activity stops and the
lights are still being active or one is on steady, this could mean I'm
pointing you into the right direction.


Quote:
> Thanks for the people that answered my question before, but I ended up
> redoing it all with sockets instead of a tcplistener. Anyway I have spent
> the last 2 weeks working on this and it is driving me insane. Sorry I
> don't have anyone else to turn to so I hope you guys can be helpful ^.^;

> Anyway the listener class seems to work fine, it accepts connections and
> everything nicely. Occasionally I get the first line of stuff sent from
> the client, but otherwise both the sending and receiving of the socket
> stream die after that. I can't read anything from it nor send anything at
> all. Anyways, as I have said I've been working on this a very long time
> and cant figure it out. Thanks for reading this everyone ^.^ The whole
> darn namespace follows:

> Option Explicit On
> Option Strict On

> Imports System
> Imports System.Net
> Imports System.Net.Sockets
> Imports System.Text
> Imports System.Threading
> Imports System.Collections

> Namespace GsSockets
> #Region " Deligates "
>     Public Delegate Sub DataArrivalDelegate(ByVal RequestID As Integer,
> ByVal Data As String)
>     Public Delegate Sub DisconnectedDelegate(ByVal RequestID As Integer)
> #End Region
>     Public Class SocketServer
>         Private sckListener As TcpListener
>         Private trdListener As Thread
>         Private objClientPool As ClientPool
>         Private intListenPort As Integer

>         ' Fired when a new client connects.
>         Public Event ClientConnected(ByVal RequestID As Integer)
>         Public Event DataArrival As DataArrivalDelegate
>         Public Event ClientDisconnected As DisconnectedDelegate

>         Public Sub New()
>         End Sub
>         Public Sub Listen(ByVal ListenPort As Integer)
>             intListenPort = ListenPort
>             objClientPool = New ClientPool()
>             trdListener = New Thread(AddressOf ListenThread)
>             trdListener.Start()
>         End Sub
>         Private Sub ListenThread()
>             Try
>                 sckListener = New TcpListener(intListenPort)
>                 sckListener.Start()
>             Catch ex As Exception
>                 MsgBox("Listen Error")
>                 ' TODO: Error Handling
>                 Exit Sub
>             End Try
>             Do While True
>                 Dim sckClient As Socket = sckListener.AcceptSocket()
>                 If sckClient.Connected Then
>                     Dim objConnectedSocket As New Client(sckClient)
>                     objClientPool.Add(CType(sckClient.Handle.ToInt32,
> Integer), objConnectedSocket)
>                     AddHandler objConnectedSocket.DataArrival, AddressOf
> DataArrivalMethod
>                     AddHandler objConnectedSocket.ClientDisconnected,
> AddressOf ClientDisconnectedMethod
>                         RaiseEvent ClientConnected(CType
> (sckClient.Handle.ToInt32, Integer))
>                 End If
>             Loop
>         End Sub
>         Public Sub Close()
>             sckListener.Stop()
>             trdListener.Abort()
>             Try
>                 objClientPool.Dispose()
>             Catch
>             End Try
>         End Sub
>         Public Sub Disconnect(ByVal RequestID As Integer)
>             objClientPool.Remove(RequestID)
>         End Sub
>         Public Sub SendData(ByVal RequestID As Integer, ByVal Data As
> String)
>             objClientPool.SendData(RequestID, Data)
>         End Sub
>         Public Sub Broadcast(ByVal Data As String)
>             objClientPool.Broadcast(Data)
>         End Sub
>         Private Sub DataArrivalMethod(ByVal RequestID As Integer, ByVal
> Data As String)
>             RaiseEvent DataArrival(RequestID, Data)
>         End Sub
>         Private Sub ClientDisconnectedMethod(ByVal RequestID As Integer)
>             RaiseEvent ClientDisconnected(RequestID)
>         End Sub
>     End Class

>     Public Class ClientPool
>         Private ClientTable As New Hashtable()

>         Public Sub Add(ByVal RequestID As Integer, ByVal Socket As
> Client)
>             Try
>                 ClientTable.Add(RequestID, Socket)
>             Catch ex As Exception
>                 ' TODO: Error handling
>             End Try
>         End Sub
>         Public Sub Remove(ByVal RequestID As Integer)
>             Try
>                 Dim connectedSocket As Client = CType(ClientTable.Item
> (RequestID), Client)
>                 connectedSocket.CloseSocket()
>                 ClientTable.Remove(RequestID)
>             Catch ex As Exception
>                 ' TODO: Error Handling
>             End Try
>         End Sub
>         Public Sub SendData(ByVal RequestID As Integer, ByVal Data As
> String)
>             Try
>                 Dim sckSocket As Client = CType(ClientTable.Item
> (RequestID), Client)
>                 sckSocket.SendData(Data)
>             Catch ex As Exception
>                 ' TODO: Error Handling
>             End Try
>         End Sub
>         Public Sub Broadcast(ByVal Data As String)
>             Dim objClient As Client
>             Dim key As Integer

>             Try
>                 For Each key In ClientTable.Keys
>                     objClient = CType(ClientTable.Item(key), Client)
>                     objClient.SendData(Data)
>                 Next
>             Catch ex As Exception
>                 ' TODO: Error Handling
>             End Try
>         End Sub
>         Public Sub Dispose()
>             Dim key As Integer
>             Try
>                 For Each key In ClientTable.Keys
>                     Dim sckSocket As Client = CType(ClientTable.Item
> (key), Client)
>                     sckSocket.CloseSocket()
>                 Next
>             Catch ex As Exception
>                 ' TODO: Error Handling
>             End Try
>         End Sub

>     End Class

>     Public Class Client
>         Private trdClient As Thread
>         Private sckClient As Socket
>         Private readBuffer(32767) As Byte

>         Public Event DataArrival As DataArrivalDelegate
>         Public Event ClientDisconnected As DisconnectedDelegate

>         Public Sub New(ByVal sckSocket As Socket)
>             sckClient = sckSocket
>             sckClient.BeginReceive(readBuffer, 0, 32767,
> SocketFlags.None, AddressOf DataArrivalThread, Nothing)
>         End Sub
>         Public Sub SendData(ByVal Data As String)
>             Dim byteData() As Byte
>             byteData = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
>             SyncLock sckClient
>                 sckClient.Send(byteData)
>             End SyncLock
>         End Sub
>         Private Sub DataArrivalThread(ByVal ar As IAsyncResult)
>             Dim intReadBytes As Integer
>             Dim strData As String
>             Try
>                 Do While True
>                     SyncLock sckClient
>                         ' Stop async read to get the data
>                         intReadBytes = sckClient.EndReceive(ar)
>                     End SyncLock

>                     sckClient.Receive(readBuffer, 0, sckClient.Available,
> SocketFlags.None)
>                     strData = Encoding.ASCII.GetString(readBuffer, 0,
> intReadBytes - 1)
>                     RaiseEvent DataArrival(CType
> (sckClient.Handle.ToInt32, Integer), strData)
>                     SyncLock sckClient
>                         ' Restart async read
>                         sckClient.BeginReceive(readBuffer, 0, 32767,
> SocketFlags.None, AddressOf DataArrivalThread, Nothing)
>                     End SyncLock
>                 Loop
>             Catch ex As Exception
>                 ' TODO: Error Handling
>                 CloseSocket()
>             End Try
>         End Sub
>         Public Sub CloseSocket()
>             RaiseEvent ClientDisconnected(CType(sckClient.Handle.ToInt32,
> Integer))
>             sckClient.Shutdown(SocketShutdown.Both)
>             sckClient.Close()
>         End Sub
>     End Class
> End Namespace



Sun, 24 Jul 2005 14:19:11 GMT  
 Socket nightmare


Quote:
> There's going to be two packects sent.  One confirming the existance
> of the item and the second sending the actual header, article or body
> information.

> This is where I think you're having the problem. When one packet
> arrives, there's no back and forth communications regarding the
> second.  It is sent automatically.

This doesn't seem to be the problem, I tried playing with it a little
more. I tried flooding the client I am connecting with sends, and
something happened. It dumped all the sends at once and then crashed. It
crashed because my CloseSocket sub was faulty (the very last one) however
that means that the DataArrival thread is getting an exception and
closing the socket, and I don't know why. After some investigation, the
error thrown is "Object reference not set to an instance of an object."
And i'm not sure how this could apply...

~Gray



Mon, 25 Jul 2005 02:25:27 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Trouble with System.Net.Sockets.Socket under Windows 98

2. System.Net.Sockets.Socket Problem

3. System.Net.Sockets.Socket State

4. system.net.sockets.socket async server example

5. Detect Remote Disconnection System.Net.Sockets.Socket

6. System.Net.Sockets.Socket.EndReceive has a bogus return value

7. Nightmares with the apostrophe!!!!!!!!!!!!

8. My Worst Nightmare: Error Accessing File

9. VBE password nightmare

10. Control Nightmare

11. RegEx - my personal illogical nightmare

12. Nightmare with ASP.NET

 

 
Powered by phpBB® Forum Software