webForumDet fria alternativet

Nätverksklass (går ej att starta 2 gånger)

.NET

10 svar · 321 visningar · startad av xcalibrate

Medlem sedan aug. 2002136 inlägg
Frågan#1

Hej, jag bifogar min nätverksclass skriven i VB.NET nedan. Problemet är att jag inte kan starta 2 gånger, alltså om jag startar servern första gången så kan en användare ansluta. Stänger jag då anslutningen och försöker starta servern igen, startas den inte.

Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System.Text

Public Class NetworkingClass
Public Event Begin_Connect(ByVal RemoteEp As IPEndPoint)
Public Event Connect_Complete(ByVal RemoteEp As IPEndPoint)
Public Event Data_Recieved(ByVal Data As Byte(), ByVal Size As Integer)
Public Event Begin_Send(ByVal Data As Byte(), ByVal Size As Integer)
Public Event Send_Complete(ByVal Sent As Integer)
Public Event Started(ByVal Ep As IPEndPoint, ByVal Port As Integer)
Public Event Connection_Accepted(ByVal RemoteEp As IPEndPoint)
Public Event Exception(ByVal Ex As Exception)
Public Event Begin_Receive()
Public Event Closed()

Public S As New Socket(2, 1, 6)
Dim Ls As New Socket(2, 1, 6)

Private Sent As Long
Private Recv As Long
Private Est As Date

Public Sub New()
    S = New Socket(2, 1, 6)
End Sub

Private Class StateObject
    Public Worksocket As Socket = Nothing
    Public BufferSize As Integer = 1025
    Public Buffer(1025) As Byte
    Public Sb As New StringBuilder
End Class

Public ReadOnly Property DataSent() As Long
    Get
        Return Sent
    End Get
End Property

Public ReadOnly Property ConnectionEstablished() As Date
    Get
        Return Est
    End Get
End Property

Public ReadOnly Property DataRecieved() As Long
    Get
        Return Recv
    End Get
End Property

Public Sub Connect(ByVal Ip As String, ByVal Port As Integer)
    Try
        If S.Connected Then S.Close()
        S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
        Dim Ep As New IPEndPoint(IPAddress.Parse(Ip), Port)
        S = New Socket(Ep.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
        Dim IpHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName)
        Dim LocalEP As New IPEndPoint(IpHostInfo.AddressList(0), 2266)
        S.Bind(LocalEP)
        S.BeginConnect(Ep, AddressOf ConnectCallback, S)
        RaiseEvent Begin_Connect(Ep)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub

Public Sub ConnectCallback(ByVal Ar As IAsyncResult)
    Try
        S = CType(ar.AsyncState, Socket)
        S.EndConnect(Ar)
        BeginReceive(S)
        Dim Ep As IPEndPoint = S.RemoteEndPoint
        Est = DateAndTime.Now
        RaiseEvent Connect_Complete(Ep)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub

Public Sub BeginReceive(ByVal Socket As Socket)
    Try
        Dim State As New StateObject
        state.Worksocket = Socket
        Socket.BeginReceive(State.Buffer, 0, State.BufferSize, 0, New AsyncCallback(AddressOf ReceieveCallback), State)
        RaiseEvent Begin_Receive()
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub ReceieveCallback(ByVal Ar As IAsyncResult)
    Try
        Dim State As StateObject = CType(Ar.AsyncState, StateObject)
        Dim Handler As Socket = State.Worksocket
        Dim Read As Integer = Handler.EndReceive(Ar)

        If Read = 0 Then
            S.Close()
            RaiseEvent Closed()
            Exit Sub
        End If

        BeginReceive(S)

        RaiseEvent Data_Recieved(State.Buffer, Read)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub Start(ByVal Port As Integer)
    Try
        MsgBox("start")
        Dim IpHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName)
        Dim LocalEP As New IPEndPoint(IpHostInfo.AddressList(0), Port)
        Ls.Bind(LocalEP)
        Ls.Listen(1000)
        Ls.BeginAccept(AddressOf AcceptCallback, Ls)
        RaiseEvent Started(LocalEP, Port)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub AcceptCallback(ByVal Ar As IAsyncResult)
    Try
        Dim Ls As Socket = CType(Ar.AsyncState, Socket)
        S = Ls.EndAccept(Ar)
        Dim Ep As IPEndPoint = S.RemoteEndPoint
        BeginReceive(S)
        Ls.BeginAccept(AddressOf AcceptCallback, Ls)
        RaiseEvent Connect_Complete(Ep)
    Catch sexp As SocketException
        Debug.WriteLine(sexp.ToString & vbCrLf)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub Send(ByVal Data As String)
    Try
        Dim Buffer(1024) As Byte
        Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
        S.BeginSend(Buffer, 0, Data.Length, 0, AddressOf SendCallback, S)
        RaiseEvent Begin_Send(Buffer, Buffer.Length)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub Send(ByVal Data() As Byte)
    Try
        S.BeginSend(Data, 0, Data.Length, 0, AddressOf SendCallback, S)
        RaiseEvent Begin_Send(Data, Data.Length)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub SendCallback(ByVal Ar As IAsyncResult)
    Try
        Dim Socket As Socket = CType(Ar.AsyncState, Socket)
        Dim BytesSent As Integer
        BytesSent = Socket.EndSend(Ar)
        RaiseEvent Send_Complete(BytesSent)
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try
End Sub
Public Sub Close()
    Try
        S.Shutdown(SocketShutdown.Both)
        S.Close()
        RaiseEvent Closed()
    Catch ex As Exception
        RaiseEvent Exception(ex)
        Debug.WriteLine(ex.ToString)
    End Try

    S = Nothing
End Sub

End Class

Försök hitta flera fel om ni kan och notera att den funkar helt bra annars, tänkte om ni hade lite tips som gör den bättre och snabbare vid sidan av mitt problem jag besrkev överst.

Medlem sedan feb. 20002 300 inlägg
#2

Använd kodtaggar, snälla. :x

Medlem sedan aug. 20003 575 inlägg
#3

Du kan inte ha två program igång som samtidigt lyssnar på samma port.

Medlem sedan aug. 2002136 inlägg
#4

Men jag har inte två program, utan jag stänger anslutningne och försöker lyssnar igen med samma program. Det är där problemet ligger. Den lyssnar inte igen vid andra försöket efter jag stängt anslutningen första gången jag lyssnade.

Medlem sedan aug. 2002136 inlägg
#5

Med taggar:

Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System.Text

Public Class NetworkingClass
    Public Event Begin_Connect(ByVal RemoteEp As IPEndPoint)
    Public Event Connect_Complete(ByVal RemoteEp As IPEndPoint)
    Public Event Data_Recieved(ByVal Data As Byte(), ByVal Size As Integer)
    Public Event Begin_Send(ByVal Data As Byte(), ByVal Size As Integer)
    Public Event Send_Complete(ByVal Sent As Integer)
    Public Event Started(ByVal Ep As IPEndPoint, ByVal Port As Integer)
    Public Event Connection_Accepted(ByVal RemoteEp As IPEndPoint)
    Public Event Exception(ByVal Ex As Exception)
    Public Event Begin_Receive()
    Public Event Closed()

    Public S As New Socket(2, 1, 6)
    Dim Ls As New Socket(2, 1, 6)

    Private Sent As Long
    Private Recv As Long
    Private Est As Date

    Public Sub New()
        S = New Socket(2, 1, 6)
    End Sub

    Private Class StateObject
        Public Worksocket As Socket = Nothing
        Public BufferSize As Integer = 1025
        Public Buffer(1025) As Byte
        Public Sb As New StringBuilder
    End Class

    Public ReadOnly Property DataSent() As Long
        Get
            Return Sent
        End Get
    End Property

    Public ReadOnly Property ConnectionEstablished() As Date
        Get
            Return Est
        End Get
    End Property

    Public ReadOnly Property DataRecieved() As Long
        Get
            Return Recv
        End Get
    End Property

    Public Sub Connect(ByVal Ip As String, ByVal Port As Integer)
        Try
            If S.Connected Then S.Close()
            S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
            Dim Ep As New IPEndPoint(IPAddress.Parse(Ip), Port)
            S = New Socket(Ep.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
            Dim IpHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName)
            Dim LocalEP As New IPEndPoint(IpHostInfo.AddressList(0), 2266)
            S.Bind(LocalEP)
            S.BeginConnect(Ep, AddressOf ConnectCallback, S)
            RaiseEvent Begin_Connect(Ep)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub

    Public Sub ConnectCallback(ByVal Ar As IAsyncResult)
        Try
            S = CType(ar.AsyncState, Socket)
            S.EndConnect(Ar)
            BeginReceive(S)
            Dim Ep As IPEndPoint = S.RemoteEndPoint
            Est = DateAndTime.Now
            RaiseEvent Connect_Complete(Ep)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub

    Public Sub BeginReceive(ByVal Socket As Socket)
        Try
            Dim State As New StateObject
            state.Worksocket = Socket
            Socket.BeginReceive(State.Buffer, 0, State.BufferSize, 0, New AsyncCallback(AddressOf ReceieveCallback), State)
            RaiseEvent Begin_Receive()
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub ReceieveCallback(ByVal Ar As IAsyncResult)
        Try
            Dim State As StateObject = CType(Ar.AsyncState, StateObject)
            Dim Handler As Socket = State.Worksocket
            Dim Read As Integer = Handler.EndReceive(Ar)

            If Read = 0 Then
                S.Close()
                RaiseEvent Closed()
                Exit Sub
            End If

            BeginReceive(S)

            RaiseEvent Data_Recieved(State.Buffer, Read)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub Start(ByVal Port As Integer)
        Try
            MsgBox("start")
            Dim IpHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName)
            Dim LocalEP As New IPEndPoint(IpHostInfo.AddressList(0), Port)
            Ls.Bind(LocalEP)
            Ls.Listen(1000)
            Ls.BeginAccept(AddressOf AcceptCallback, Ls)
            RaiseEvent Started(LocalEP, Port)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub AcceptCallback(ByVal Ar As IAsyncResult)
        Try
            Dim Ls As Socket = CType(Ar.AsyncState, Socket)
            S = Ls.EndAccept(Ar)
            Dim Ep As IPEndPoint = S.RemoteEndPoint
            BeginReceive(S)
            Ls.BeginAccept(AddressOf AcceptCallback, Ls)
            RaiseEvent Connect_Complete(Ep)
        Catch sexp As SocketException
            Debug.WriteLine(sexp.ToString & vbCrLf)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub Send(ByVal Data As String)
        Try
            Dim Buffer(1024) As Byte
            Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(Data)
            S.BeginSend(Buffer, 0, Data.Length, 0, AddressOf SendCallback, S)
            RaiseEvent Begin_Send(Buffer, Buffer.Length)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub Send(ByVal Data() As Byte)
        Try
            S.BeginSend(Data, 0, Data.Length, 0, AddressOf SendCallback, S)
            RaiseEvent Begin_Send(Data, Data.Length)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub SendCallback(ByVal Ar As IAsyncResult)
        Try
            Dim Socket As Socket = CType(Ar.AsyncState, Socket)
            Dim BytesSent As Integer
            BytesSent = Socket.EndSend(Ar)
            RaiseEvent Send_Complete(BytesSent)
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try
    End Sub
    Public Sub Close()
        Try
            S.Shutdown(SocketShutdown.Both)
            S.Close()
            RaiseEvent Closed()
        Catch ex As Exception
            RaiseEvent Exception(ex)
            Debug.WriteLine(ex.ToString)
        End Try

        S = Nothing
    End Sub
End Class
Medlem sedan maj 20021 466 inlägg
#6

Anropa Ls.Close och Ls.Dispose för att stänga och frigöra socketens resurser. Gör du inte det kommer den att fortsätta ta emot anslutningar på den bundna porten.

Medlem sedan aug. 2002136 inlägg
#7

Finns inget som heter Dispose under Ls eller S. Bara close

Medlem sedan maj 20012 812 inlägg
#8

Det jag har upptäckt när jag använt mig av TCP/IP är att själva porten fortfarande är öppen ett litet tag efter det att jag har stängt min koppling.

Om jag däremot stänger ner programmet så stängs porten direkt, men stänger jag bara socketsen så är porten fortfarande öppen/låst ett litet tag till.

Varför har jag ingen anning om och jag hittade inget bra svar när jag sökte på nätet om hur man skulle göra, allt jag hittade var att det var så det fungerade med TCP/IP. Jag hittade dock ett program som alltid stängde ner sin port när socketsen stängdes, och fast jag tog den koden och körde i mitt eget program så stängdes inte porten, men likförbannat så stängdes porten i det andra programmet, märkligt...

Så jag tror inte du kan komma runt detta problem, men om du skulle hitta en lösning (min var att använd UDP :)) så får du gärna skriva svaret här, för jag är mycket intresserad av den informationen...

- M

Medlem sedan aug. 2002136 inlägg
#9

Markus E hade rätt, eller ganska rätt, allt fungerar somd et ska nu efter jag la till Ls.Close också och Ls = Nothing, istället för att bara stänga S

Medlem sedan maj 20021 466 inlägg
#10

Dispose ska finnas. Att sätta till Nothing gör ingenting. Dispose gör däremot att resurserna frigörs direkt istället för senare. Det är inte nödvändigt men kan vara bra att göra.

Bra att Close fungerade dock. Om du anropar Dispose kommer nog Close också att anropas.

Medlem sedan aug. 2002136 inlägg
#11

Okej, det som är synd är ju att det inte finns nån Dispose :D

263 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
122 ms — deklarationer (db)
0 ms — hämta statistik (cache)
138 ms — hämta tråd, inlägg och bilagor (db)
119 ms — ändringar (db)