أرجوا من السادة المخطصين في برمجة vb.net
شرح كيفية أستعمال2 class المرفقين مع الموضوع وشكرا
client
server
شرح كيفية أستعمال2 class المرفقين مع الموضوع وشكرا
client
كود :
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Public Class Winsock
Private Class StateObject
' Socket cliente.
' Client socket.
Public workSocket As Socket = Nothing
' Tamaٌo del buffer de recepcion.
' Size of receive buffer.
Public Const BufferSize As Integer = 8192
' Buffer de recepcion.
' Receive buffer.
Public buffer(BufferSize) As Byte
' Ultimos Datos recibidos.
' Received data string.
Public UltimosDatos As String
End Class 'StateObject
#Region " VARIABLES "
' Creo un socket TCP/IP.
' Create a TCP/IP socket.
Private Client As Socket
' Estado Inicial.
' Initial state.
Private SockState As States = States.Closed
' Indica si el socket debera reconectar automaticamente si hay una desconexion.
' It indicates if socket connect automatically if there is a disconnection.
Private LReConnect As Boolean = False
' Tiempo de Espera desde la desconexion hasta el nuevo intento de conexion.(milisegundos)
' esperar 10 segundos antes del reintento.
' Time of Delay from the disconnection to the new attempt of connection. (milliseconds)
' wait 10 seconds before reconnect.
Private LWait As Integer = 10000
' Valores para reconexion. ip y port.
' Values to reconnect. ip and port.
Private OpTimer As String = String.Empty
' Timer que intentara reconectar.
' Timer that tried to reconnect
Private stateTimer As Timer
Private LVerifyConnexion As Boolean
Private LInterval As Integer
Private stateTimerVer As Timer
#End Region
#Region " FUNCIONES PRIVADAS "
Private Sub ChangeState(ByVal NuevoEstado As States)
SockState = NuevoEstado
RaiseEvent StateChanged(NuevoEstado)
End Sub 'ChangeState
Private Sub ReConnectSock(ByVal State As String)
Try
Dim timerDelegate As TimerCallback = AddressOf MyTimerCallBack
stateTimer = New Timer(timerDelegate, State, LWait, LWait)
Catch
LReConnect = False
End Try
End Sub
Private Sub Verify()
Try
Dim timerDelegate As TimerCallback = AddressOf MyTimerCallBackVer
stateTimerVer = New Timer(timerDelegate, Nothing, LInterval, LInterval)
Catch
LVerifyConnexion = False
End Try
End Sub
#End Region
#Region " FUNCIONES PUBLICAS "
Public Function IsConnected() As Boolean
' Asي se puede determinar si un socket estل conectado.
' This is how you can determine whether a socket is still connected.
Dim blockingState As Boolean
Try
blockingState = Client.Blocking
Dim tmp(0) As Byte
Client.Blocking = False
Client.Send(tmp, 0, 0)
Return True
Catch e As SocketException
' 10035 == WSAEWOULDBLOCK
If e.NativeErrorCode.Equals(10035) Then
'Esta conectado pero no puede enviar
If Not GetState.Equals(States.Closed) Or Not GetState.Equals(States.Closing) Then
Call Close()
End If
Return False
Else
Return False
End If
Catch e As Exception
Return False
Finally
If Not IsNothing(Client) Then
If Client.Connected = True Then Client.Blocking = blockingState
End If
End Try
End Function 'IsConnected
Public Function IsFreeToSend() As Boolean
If IsConnected() And GetState.Equals(States.Connected) Then
Return True
Else
Return False
End If
End Function 'IsFreeToSend
Public Function RemoteHostIP() As String
Try
Dim Idcliente As IPEndPoint = Client.RemoteEndPoint
Return Idcliente.Address.ToString
Catch
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
Return ""
End Try
End Function 'RemoteHostIP
Public Function RemoteHostPort() As String
Try
Dim Idcliente As IPEndPoint = Client.RemoteEndPoint
Return Idcliente.Port.ToString
Catch
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
Return ""
End Try
End Function 'RemoteHostPort
Public Function LocalPort() As String
Try
Dim Idcliente As IPEndPoint = Client.LocalEndPoint
Return Idcliente.Port.ToString
Catch
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
Return ""
End Try
End Function 'LocalPort
Public Function LocalIP() As String
Try
Dim Idcliente As IPEndPoint = Client.LocalEndPoint
Return Idcliente.Address.ToString
Catch
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
Return ""
End Try
End Function 'LocalIP
#End Region
#Region " EVENTOS "
Public Event Connected()
Public Event ErrorSocket(ByVal Number As Integer, ByVal Message As String)
Public Event SendComplete()
Public Event DataArrival(ByVal Data As String)
Public Event Disconnected()
Public Event StateChanged(ByVal State As String)
#End Region
#Region " PROPIEDADES "
Public ReadOnly Property GetState() As States
Get
Return SockState
End Get
End Property 'GetState
Public Property ReConnect() As Boolean
Get
ReConnect = LReConnect
End Get
Set(ByVal value As Boolean)
LReConnect = value
End Set
End Property 'ReConnect
Public Property WaitMilliseconds() As Integer
Get
WaitMilliseconds = LWait
End Get
Set(ByVal value As Integer)
LWait = IIf(value < 10000, 10000, value)
End Set
End Property 'WaitMilliseconds
Public Property VerifyConnexion() As Boolean
Get
VerifyConnexion = LVerifyConnexion
End Get
Set(ByVal value As Boolean)
If LVerifyConnexion = False And value = True Then
LVerifyConnexion = value
Call Verify()
End If
LVerifyConnexion = value
End Set
End Property 'VerifyConnexion
Public Property Interval() As Integer
Get
Interval = LInterval
End Get
Set(ByVal value As Integer)
LInterval = IIf(value < 30000, 30000, value)
End Set
End Property 'WaitMilliseconds
#End Region
#Region " METODOS "
Public Sub Connect(ByVal Ip As String, ByVal Port As Integer)
' 'Compruebo si el cliente esta conectado.
If GetState <> States.Closed Then
RaiseEvent ErrorSocket(0, "Para Conectar el socket debe estar Cerrado. Estado actual : " & GetState)
Exit Sub
End If
'String que contiene los valores para reconectar.
OpTimer = Ip + vbTab + Port.ToString + vbTab
Try
Dim ipAddress As IPAddress
Dim remoteEP As IPEndPoint = Nothing
Try
ipAddress = Net.IPAddress.Parse(Ip)
remoteEP = New IPEndPoint(ipAddress, Port)
Catch ex As Exception
For i As Integer = 0 To Dns.GetHostEntry(Ip).AddressList.Length - 1
Dim Nip As String = Dns.GetHostEntry(Ip).AddressList(i).ToString
ipAddress = Net.IPAddress.Parse(Nip)
remoteEP = New IPEndPoint(ipAddress, Port)
If ipAddress.IsIPv6LinkLocal = True Or ipAddress.IsIPv6Multicast = True Or ipAddress.IsIPv6SiteLocal = True Then
remoteEP = Nothing
Else
Exit For
End If
Next
End Try
Client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Permanencia de un segundo después de llamar al método Close.
'Linger one second after calling the Close method.
Dim myOpts As New LingerOption(True, 1)
Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, _
myOpts)
ChangeState(States.Connecting)
'si he de reconectar
If LReConnect = True And IsNothing(stateTimer) Then Call ReConnectSock(OpTimer)
' Conecto con el endpoint.
' Connect to the remote endpoint.
Client.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), Client)
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
Catch ex1 As Exception
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, ex1.Message)
End Try
End Sub 'Connect
Public Sub SendData(ByVal Data As String)
Try
ChangeState(States.Sending)
' Envيo los datos
' Send data to the remote device.
Send(Client, Data)
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
End Try
End Sub 'Sendata
Public Sub Close()
Try
If GetState <> States.Closed Then
If GetState = States.Connected Then Client.Shutdown(SocketShutdown.Both)
ChangeState(States.Closing)
Client.BeginDisconnect(False, New AsyncCallback(AddressOf CloseCallBack), Client)
End If
Catch ex1 As SocketException
ChangeState(States.Closed)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
Catch ex As Exception
ChangeState(States.Closed)
RaiseEvent ErrorSocket(Err.Number, Err.Description)
End Try
End Sub 'Close
Private Sub Send(ByVal client As Socket, ByVal data As String)
Try
' Convertir la cadena a bytes utilizando la codificaciَn ASCII.
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.Default.GetBytes(data)
' Empezar a enviar datos
' Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), client)
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
Catch ex1 As Exception
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, ex1.Message)
End Try
End Sub 'Send
Private Sub Receive(ByVal client As Socket)
Try
' Creo el objeto
' Create the state object.
Dim state As New StateObject
state.workSocket = client
' Empezar a recibir datos
' Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
Catch ex1 As Exception
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, ex1.Message)
End Try
End Sub 'Receive
#End Region
#Region " SUB ASYNC "
Private Sub ConnectCallback(ByVal ar As IAsyncResult)
' Recupero el socket
' Retrieve the socket from the state object.
Dim Client As Socket = CType(ar.AsyncState, Socket)
Try
' Se completa la conexiَn
' Complete the connection.
Client.EndConnect(ar)
ChangeState(States.Connected)
RaiseEvent Connected()
' Empezamos a recibir
' Receive the response from the remote device.
Receive(Client)
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
Catch ex1 As Exception
ChangeState(States.Error)
RaiseEvent ErrorSocket(Err.Number, ex1.Message)
End Try
End Sub 'ConnectCallback
Private Sub SendCallback(ByVal ar As IAsyncResult)
Try
' Recupero el socket
' Retrieve the socket from the state object.
Dim client As Socket = CType(ar.AsyncState, Socket)
' Completar el envيo de datos al dispositivo remoto.
' Complete sending the data to the remote device.
Dim bytesSent As Integer = client.EndSend(ar)
ChangeState(States.Connected)
' Seٌal de que todo se ha enviado
' Signal that all bytes have been sent.
RaiseEvent SendComplete()
Catch ex As SocketException
ChangeState(States.Error)
RaiseEvent ErrorSocket(ex.ErrorCode, ex.Message)
End Try
End Sub 'SendCallback
Private Sub ReceiveCallback(ByVal ar As IAsyncResult) 'ReceiveCallback
' Recupero el objeto y el socket
' Retrieve the state object and the client socket
' from the asynchronous state object.
Try
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim client As Socket = state.workSocket
Dim bytesRead As Integer = client.EndReceive(ar)
If bytesRead < 1 Then
If Not GetState.Equals(States.Closed) And Not GetState.Equals(States.Closing) Then Call Close()
Else
' Compruebo si la linea acaba en <EOF>
Dim Linea As String = Nothing
Linea = Encoding.Default.GetString(state.buffer, 0, bytesRead)
If Linea.EndsWith("<EOF>") Then
state.UltimosDatos += Encoding.Default.GetString(state.buffer, 0, bytesRead)
'Genero el evento de la recepcion del mensaje
RaiseEvent DataArrival(state.UltimosDatos)
state.UltimosDatos = String.Empty
Else
'almaceno hasta que acabe en <EOF>
state.UltimosDatos += Encoding.Default.GetString(state.buffer, 0, bytesRead)
End If
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
End If
Catch ex1 As SocketException
If Not GetState.Equals(States.Closed) And Not GetState.Equals(States.Closing) Then Call Close()
Catch ex As Exception
If Not GetState.Equals(States.Closed) And Not GetState.Equals(States.Closing) Then Call Close()
End Try
End Sub 'ReceiveCallback
Private Sub CloseCallBack(ByVal ar As IAsyncResult)
If Not GetState.Equals(States.Closed) Then
ChangeState(States.Closed)
RaiseEvent Disconnected()
End If
End Sub 'CloseCallBack
Private Sub MyTimerCallBack(ByVal State As Object)
Try
If LReConnect = False Then
If Not IsNothing(stateTimer) Then stateTimer.Dispose()
stateTimer = Nothing
Exit Sub
End If
If GetState.Equals(States.Error) Then ChangeState(States.Closed)
If GetState.Equals(States.Closed) Then
Dim optimer As String = DirectCast(State, String)
Dim TheValues As String() = Split(optimer, vbTab)
Call Connect(TheValues(0), CType(TheValues(1), Integer))
End If
Catch
If Not IsNothing(stateTimer) Then stateTimer.Dispose()
stateTimer = Nothing
End Try
End Sub 'MyTimerCallBack
Private Sub MyTimerCallBackVer(ByVal State As Object)
Try
If LVerifyConnexion = False Then
If Not IsNothing(stateTimerVer) Then stateTimerVer.Dispose()
stateTimerVer = Nothing
Exit Sub
End If
If GetState.Equals(States.Connected) Then
If IsConnected.Equals(False) Then
If GetState.Equals(States.Connected) Then Call Close()
End If
End If
Catch
If Not IsNothing(stateTimerVer) Then stateTimerVer.Dispose()
stateTimerVer = Nothing
End Try
End Sub 'MyTimerCallBackVer
#End Region
#Region " ENUM "
Public Enum States
Closed = 0
Deleted = 1
Sending = 3
Connecting = 6
Connected = 7
Closing = 8
[Error] = 9
End Enum 'States
#End Region
End Classserver
كود :
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Public Class Winsock
Private Class StateObject
' Socket Cliente.
Public Socket As Socket = Nothing
' Tamaٌo del buffer.
Public Const BufferSize As Integer = 8192
' Buffer de recepciَn.
Public buffer(BufferSize) As Byte
' Ultima cadena recibida.
Public UltimosDatos As String
'Indice de conexion asignado.
Public IndexCli As Integer
'Estado del Socket.
Public SockState As States = States.Closed
End Class 'StateObject
#Region " VARIABLES "
' Create a TCP/IP socket to Listen.
Private Listener As Socket
'Estado del socket que escucha.
Private SockState As States = States.Closed
'Aqui se guarda la informacion de todos los clientes conectados
Private Clientes As New Hashtable()
''Ultimo indice que se ha aٌadido a la coleccion
'Private NuevaCon As Integer
''Numero de conexion mayor
'Private NconIP As Integer
'Informo a CloseCallBack para que cierre el listener y limpie la hashtable.
Private CloseAllSockets As Boolean
#End Region
#Region " EVENTOS "
Public Event ConnectionRequest(ByVal Index As Integer)
Public Event DataArrival(ByVal Index As Integer, ByVal Data As String)
Public Event Disconnected(ByVal Index As Integer)
Public Event ErrorSocket(ByVal Index As Integer, ByVal Number As Integer, ByVal Message As String, ByVal Method As String)
Public Event SendComplete(ByVal Index As Integer)
Public Event StateChanged(ByVal Index As Integer, ByVal State As String)
#End Region
#Region " METODOS "
Public Sub Listen(ByVal Ip As String, ByVal Port As Integer)
If GetState(0) = States.Listening Then Exit Sub
Try
Dim ipAddress As IPAddress = Nothing
Dim Nip As String = String.Empty
Try
IPAddress = Net.IPAddress.Parse(Ip)
Catch ex As Exception
For i As Integer = 0 To Dns.GetHostEntry(Ip).AddressList.Length - 1
Nip = Dns.GetHostEntry(Ip).AddressList(i).ToString
ipAddress = Net.IPAddress.Parse(Nip)
Dim value As Boolean
value = ipAddress.IsIPv6LinkLocal
If value = False Then Exit For
Next
'Ip = Dns.GetHostEntry(Ip).AddressList(0).ToString
'ipAddress = Net.IPAddress.Parse(Ip)
End Try
Dim localEndPoint As New IPEndPoint(ipAddress, Port)
Listener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Permite enlazar un socket para obtener acceso exclusivo.En este caso es Falso.
Listener.ExclusiveAddressUse = False
'Permite enlazar el socket a una direcciَn que ya estل en uso
Listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
Listener.Bind(localEndPoint)
Listener.Listen(100)
ChangeState(0, States.Listening)
Listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), Listener)
Catch
If Not IsNothing(Listener) Then Listener.Close()
ChangeState(0, States.Error)
RaiseEvent ErrorSocket(0, Err.Number, Err.Description, "Listen")
End Try
End Sub 'Listen
Public Sub Close(ByVal Index As Integer)
Dim Cliente As New StateObject
Try
Select Case Index
Case 0
Dim Keycol As New Collection
For Each Cliente In Clientes.Values
Keycol.Add(Cliente.IndexCli)
Next
If Keycol.Count > 0 Then
'Informo a CloseCallBack para que cierre el listener y limpie la hashtable.
CloseAllSockets = True
For i As Integer = 1 To Keycol.Count
Close(CType(Keycol.Item(i), Integer))
Next
End If
If Keycol.Count = 0 Then
Clientes.Clear()
'Compruebo el estado del listener antes de cambiar a Closed.
'para no disparar el evento Disconnected, en el caso de que ya estuviera
'desconectado al cerrar el listener.
Dim Actualstate As States = SockState
'Cambio el estado del listener.
If Actualstate <> States.Closed Then ChangeState(Index, States.Closed)
'Cierro el socket que escucha.
If Not IsNothing(Listener) Then Listener.Close()
'Genero el evento disconnected de listener
If Actualstate <> States.Closed Then RaiseEvent Disconnected(0)
Else
'Limpio la colecion de key.
Keycol.Clear()
End If
Case Else
If Clientes.ContainsKey(Index) Then
'Obtengo la informacion del cliente solicitado.
Cliente = Clientes(Index)
If GetState(Index) <> States.Closed And GetState(Index) <> States.Closing Then
'Cierro la conexion con el cliente.
If Cliente.Socket.Connected = True Then Cliente.Socket.Shutdown(SocketShutdown.Both)
ChangeState(Index, States.Closing)
''''''''''''''''''''''''
Dim handler As Socket = Cliente.Socket
handler.BeginDisconnect(False, New AsyncCallback(AddressOf CloseCallBack), Cliente)
End If
End If
End Select
Catch ex1 As SocketException
ChangeState(Index, States.Closed)
Cliente.Socket.Close()
Catch ex As Exception
ChangeState(Index, States.Closed)
RaiseEvent ErrorSocket(Index, Err.Number, Err.Description, "Close")
End Try
End Sub 'Close
Public Sub SendData(ByVal Index As Integer, ByVal Data As String)
Try
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.Default.GetBytes(Data)
Dim Cliente As StateObject = Clientes(Index)
Dim handler As Socket = Cliente.Socket
' Begin sending the data to the remote device.
ChangeState(Index, States.Sending)
'SyncLock Me
handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), Cliente)
'End SyncLock
Catch
ChangeState(Index, States.Error)
RaiseEvent ErrorSocket(Index, Err.Number, Err.Description, "SendData")
End Try
End Sub 'Send
Public Sub SendDataToAll(ByVal Data As String, ByVal Exclude As Integer)
Dim Cliente As New StateObject
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.Default.GetBytes(Data)
Try
'Recorro todos los clientes conectados, y les envio Datos
For Each Cliente In Clientes.Values
If Not Cliente.IndexCli.Equals(Exclude) Then
Dim handler As Socket = Cliente.Socket
ChangeState(Cliente.IndexCli, States.Sending)
' Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), Cliente)
End If
Next
Catch
ChangeState(Cliente.IndexCli, States.Error)
RaiseEvent ErrorSocket(Cliente.IndexCli, Err.Number, Err.Description, "SendDataToAll - Index : " _
& Cliente.IndexCli.ToString)
End Try
End Sub 'SendDataToAll
#End Region
#Region " METODOS PRIVADOS "
Private Sub ChangeState(ByVal Index As Integer, ByVal NuevoEstado As States)
Select Case Index
Case 0
SockState = NuevoEstado
Case Else
'si se ha encontrado en la coleccion y esta conectado
If Clientes.ContainsKey(Index) = True Then
Dim Cliente As New StateObject
Cliente = Clientes(Index)
Try
Cliente.SockState = NuevoEstado
Catch
End Try
Else
NuevoEstado = States.Deleted
End If
End Select
'SyncLock Me
RaiseEvent StateChanged(Index, CType(NuevoEstado, String))
'End SyncLock
End Sub
'Private Function ComprobarNConIp(ByVal Index As Integer) As Boolean
' 'si se ha encontrado en la coleccion y esta conectado
' If Clientes.ContainsKey(Index) = True Then
' 'si esta conectado devuelvo true
' 'si no lo esta false.
' If IsConnected(Index) Then
' Return True
' Else
' Clientes.Remove(Index)
' Return False
' End If
' Else
' Return False
' End If
'End Function
#End Region
#Region " PROPIEDADES "
Public ReadOnly Property GetState(ByVal Index As Integer) As States
Get
Select Case Index
Case 0
Return SockState
Case Else
'si se ha encontrado en la coleccion.
If Clientes.ContainsKey(Index) = True Then
Try
Dim Cliente As New StateObject
Cliente = Clientes(Index)
Return Cliente.SockState
Catch
End Try
Else
Return States.Deleted
End If
End Select
End Get
End Property
#End Region
#Region " FUNCIONES PUBLICAS "
Public Function IsConnected(ByVal Index As Integer) As Boolean
Dim Cliente As New StateObject
Try
Select Case Index
Case 0
If SockState = States.Listening Then
If Listener.Poll(1000, SelectMode.SelectRead) Or _
Listener.Poll(1000, SelectMode.SelectWrite) Or _
Listener.Poll(1000, SelectMode.SelectError) = False Then
Return True
End If
End If
Case Else
'si se ha encontrado en la coleccion.
If Clientes.ContainsKey(Index) = True Then
Cliente = Clientes(Index)
' This is how you can determine whether a socket is still connected.
Dim blockingState As Boolean
Try
blockingState = Cliente.Socket.Blocking
Dim tmp(0) As Byte
Cliente.Socket.Blocking = False
Cliente.Socket.Send(tmp, 0, 0)
Return True
Catch e As SocketException
' 10035 == WSAEWOULDBLOCK
If e.NativeErrorCode.Equals(10035) Then
'Esta conectado pero no puede enviar
Call Close(Index)
Return False
Else
Return False
End If
Catch e As Exception
Return False
Finally
If Not IsNothing(Cliente.Socket) Then
If Cliente.Socket.Connected = True Then Cliente.Socket.Blocking = blockingState
End If
End Try
Else
Return False
End If
End Select
Catch
Return False
End Try
End Function 'IsConnected
Public Function IsFreeToSend(ByVal Index As Integer) As Boolean
Dim Cliente As New StateObject
Try
Select Case Index
Case 0
Return False
Case Else
'si se ha encontrado en la coleccion.
If Clientes.ContainsKey(Index) = True Then
Cliente = Clientes(Index)
'Not allowed for the state Sending
If IsConnected(Index) And GetState(Index) = States.Connected Then
Return True
End If
Else
Return False
End If
End Select
Catch
Return False
End Try
End Function 'IsFreeToSend
Public Function RemoteClientIP(ByVal Index As Integer) As String
Try
Dim Cliente As StateObject = Clientes(Index)
Dim Idcliente As IPEndPoint = Cliente.Socket.RemoteEndPoint
Return Idcliente.Address.ToString
Catch
'RaiseEvent ErrorSocket(Index, Err.Number, Err.Description, "RemoteClientIP")
Return ""
End Try
End Function 'RemoteClientIP
Public Function RemoteClientPort(ByVal Index As Integer) As String
Try
Dim Cliente As StateObject = Clientes(Index)
Dim Idcliente As IPEndPoint = Cliente.Socket.RemoteEndPoint
Return Idcliente.Port.ToString
Catch ex As Exception
'RaiseEvent ErrorSocket(Index, Err.Number, Err.Description, "RemoteClientIP")
Return ""
End Try
End Function 'RemoteClientPort
Public Function LocalIP() As String
Try
Dim Idlocal As IPEndPoint = Listener.LocalEndPoint
Return Idlocal.Address.ToString
Catch
'RaiseEvent ErrorSocket(0, Err.Number, Err.Description, "LocalIP")
Return ""
End Try
End Function 'LocalIP
Public Function LocalPort() As String
Try
Dim Idlocal As IPEndPoint = Listener.LocalEndPoint
Return Idlocal.Port.ToString
Catch
'RaiseEvent ErrorSocket(0, Err.Number, Err.Description, "LocalIP")
Return ""
End Try
End Function 'LocalPort
#End Region
#Region " SUB ASYNC "
Private Sub AcceptCallback(ByVal ar As IAsyncResult)
If GetState(0) = States.Closed Then Exit Sub
Dim state As New StateObject
'compruebo que Index le asigno.
'NuevaCon = 0
Dim handler As Socket = Nothing
Try
' Get the socket that handles the client request.
Dim listener As Socket = CType(ar.AsyncState, Socket)
' End the operation.
handler = listener.EndAccept(ar)
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
' Create the state object for the async receive.
state.Socket = handler
'Permanencia de un segundo después de llamar al método Close.
'Linger one second after calling the Close method.
Dim myOpts As New LingerOption(True, 1)
state.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, _
myOpts)
'le asigno siempre el indice 1
state.IndexCli = 1
state.SockState = States.Connected
Clientes.Add(state.IndexCli, state)
RaiseEvent ConnectionRequest(state.IndexCli)
''For i As Integer = 1 To NconIP
'' If ComprobarNConIp(i) = False Then
'' NuevaCon = i
'' Exit For
'' End If
''Next i
''If NuevaCon = 0 Then NconIP = NconIP + 1 : NuevaCon = NconIP
' ''indice de conexion del cliente.
''state.IndexCli = NuevaCon
' ''estado del socket cliente.
''state.SockState = States.Connected
''SyncLock Me
'' 'aٌado el cliente a la coleccion.
'' Clientes.Add(state.IndexCli, state)
'' ChangeState(state.IndexCli, States.Connected)
'' RaiseEvent ConnectionRequest(state.IndexCli)
''End SyncLock
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
Catch
If Not IsNothing(handler) Then
handler.Close()
Else
Call Close(0)
ChangeState(0, States.Error)
RaiseEvent ErrorSocket(0, Err.Number, Err.Description, "AcceptCallback")
End If
End Try
End Sub 'AcceptCallback
Private Sub ReceiveCallback(ByVal ar As IAsyncResult)
'Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.Socket
Try
' Read data from the client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)
If bytesRead < 1 Then
If CloseAllSockets = False Then Close(state.IndexCli)
Exit Sub
Else
'If state.IndexCli = 0 Then
' 'indice de conexion del cliente.
' state.IndexCli = CType(Encoding.Default.GetString(state.buffer, 0, bytesRead), Integer)
' 'estado del socket cliente.
' state.SockState = States.Connected
' SyncLock Me
' 'si ya existe la clave primero la elimino
' If Clientes.ContainsKey(state.IndexCli) Then Clientes.Remove(state.IndexCli)
' 'aٌado el cliente a la coleccion.
' Clientes.Add(state.IndexCli, state)
' End SyncLock
' ChangeState(state.IndexCli, States.Connected)
' 'SyncLock Me
' RaiseEvent ConnectionRequest(state.IndexCli)
' 'End SyncLock
'Else
' Compruebo si la linea acaba en <EOF>
Dim Linea As String = Nothing
Linea = Encoding.Default.GetString(state.buffer, 0, bytesRead)
If Linea.EndsWith("<EOF>") Then
state.UltimosDatos += Encoding.Default.GetString(state.buffer, 0, bytesRead)
'Genero el evento de la recepcion del mensaje
RaiseEvent DataArrival(state.IndexCli, state.UltimosDatos)
state.UltimosDatos = String.Empty
Else
' There might be more data, so store the data received so far.
state.UltimosDatos += Encoding.Default.GetString(state.buffer, 0, bytesRead)
End If
End If
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state)
'End If
Catch ex As SocketException
Close(state.IndexCli)
Exit Sub
Catch e As Exception
Exit Sub
End Try
End Sub 'ReadCallback
Private Sub SendCallback(ByVal ar As IAsyncResult)
Dim Cliente As StateObject = CType(ar.AsyncState, StateObject)
Try
' Retrieve the socket from the state object.
Dim handler As Socket = Cliente.Socket
' Complete sending the data to the remote device.
Dim bytesSent As Integer = handler.EndSend(ar)
ChangeState(Cliente.IndexCli, States.Connected)
'SyncLock Me
RaiseEvent SendComplete(Cliente.IndexCli)
'End SyncLock
Catch
ChangeState(Cliente.IndexCli, States.Error)
RaiseEvent ErrorSocket(Cliente.IndexCli, Err.Number, Err.Description, "SendCallback")
End Try
End Sub 'SendCallback
Private Sub CloseCallBack(ByVal ar As IAsyncResult)
Dim Cliente As StateObject = CType(ar.AsyncState, StateObject)
If Clientes.ContainsKey(Cliente.IndexCli) Then
If GetState(Cliente.IndexCli) <> States.Closed Then ChangeState(Cliente.IndexCli, States.Deleted)
RaiseEvent Disconnected(Cliente.IndexCli)
SyncLock Me
'Elimino el cliente de la colecion.
Clientes.Remove(Cliente.IndexCli)
End SyncLock
End If
If CloseAllSockets = True Then
If Clientes.Count = 0 Then
CloseAllSockets = False
'Cambio el estado del listener.
ChangeState(0, States.Closed)
'Cierro el socket que escucha.
Listener.Close()
'Genero el evento disconnected de listener
RaiseEvent Disconnected(0)
End If
End If
End Sub 'CloseCallBack
#End Region
#Region " ENUM "
Public Enum States
Closed = 0
Deleted = 1
Listening = 2
Sending = 3
Connecting = 6
Connected = 7
Closing = 8
[Error] = 9
End Enum
#End Region
End Class