Hello, i can't see why this code is not working.
VB.NET:
Option Strict On
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Public Class Form1
'Form Controls.
Private lblListenPort As New Label
Private txtListenPort As New TextBox
Private WithEvents btnStartStop As New Button
Private lvwMessages As New ListView
'Global Objects.
Private gListeningSocket As Socket = Nothing
Private gPort As Integer = 0
Private gListening As Boolean = False
Private gStopListening As Boolean = False
Private gConnectionIndex As Integer = -1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Setup form controls.
With Me
.Text = "Message Server"
.Size = New System.Drawing.Size(900, 600)
.Controls.Add(lvwMessages)
.Controls.Add(btnStartStop)
.Controls.Add(txtListenPort)
.Controls.Add(lblListenPort)
End With
With lblListenPort
.Text = "Listen Port:"
.Dock = DockStyle.Top
End With
With txtListenPort
.Text = "20912" 'Random port.
.Dock = DockStyle.Top
End With
With btnStartStop
.Text = "Start Listening"
.Dock = DockStyle.Top
End With
With lvwMessages
.Dock = DockStyle.Fill
.View = View.Details
.GridLines = True
.FullRowSelect = True
.MultiSelect = False
.Scrollable = True
.Columns.Add("Direction") 'Text
.Columns.Add("Conn ID") 'SubItem 1
.Columns.Add("Client IP") 'SubItem 2
.Columns.Add("Dec") 'SubItem 3
.Columns.Add("Hex") 'SubItem 4
.Columns.Add("Chr") 'SubItem 5
For Each vCol As ColumnHeader In .Columns
vCol.Width = CInt(Math.Floor(.Width / .Columns.Count)) - CInt(Math.Floor(30 / .Columns.Count))
Next
End With
End Sub
Private Sub btnStartStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartStop.Click
'Is the socket already listening?
If gListening Then
StopListening()
Exit Sub
Else
gPort = 7112 'CInt(txtListenPort.Text)
If gPort <= 0 Then MessageBox.Show("Invalid port. Please specify the port.") : Exit Sub
End If
'See if specified port is already being used. If not, bind to it.
Try
Dim vEndPoint As New IPEndPoint(IPAddress.Any, gPort)
gListeningSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
gListeningSocket.Bind(vEndPoint)
Dim vBacklog As Integer = 1000
gListeningSocket.Listen(vBacklog)
gListening = True
gStopListening = False
btnStartStop.Text = "Stop Listening"
Catch ex As Exception
MessageBox.Show("Bad port specified, or port already in use.")
Exit Sub
End Try
'Start listening.
Dim vThread As New Thread(AddressOf ListenBackground)
With vThread
.IsBackground = True
.Name = "Listener thread for port " & gPort
End With
vThread.Start()
End Sub
Private Sub ListenBackground()
'Listen in a loop until cancelled...
Do Until gStopListening
'The loop will wait until a client makes a connection attempt.
Dim vCommunicationSocket As Socket = gListeningSocket.Accept()
'If an attempt is made, accept it in the form of a new socket with which to receive/send data from/to this client.
If vCommunicationSocket.Connected = True Then
'Even though we have made a connection to a client, we're not going quit listening for further connections
'from other clients (or maybe the same client at a later date). So we will give this connection an ID so it can
'be distinguished from other connections. We do this by incrementing a counter. Its ID will be the value of
'the counter.
gConnectionIndex += 1
'The client has accepted, now spawn a thread to wait for data from the client.
Dim vThread As New Thread(AddressOf ReceiveBackground)
With vThread
.IsBackground = True
.Name = "Receiver thread for connection " & gConnectionIndex & " on port " & gPort
End With
'A single object can be passed into the thread via the Start() method's optional parameter.
'Since we need both the connection ID and the socket itself, we will pass an object that contains both.
Dim vSocketAndId As New SocketAndId
With vSocketAndId
.ConnectionId = gConnectionIndex
.ConnectionSocket = vCommunicationSocket
End With
vThread.Start(CType(vSocketAndId, Object))
End If
'Continue listening for new connections...
Loop
'Stop listening.
gListeningSocket.Close()
gListening = False
ReportDoneListening_CrossThread()
End Sub
Private Sub ReceiveBackground(ByVal Args As Object)
Dim vConnectionId As Integer = CType(Args, SocketAndId).ConnectionId
Dim vConnectionSocket As Socket = CType(Args, SocketAndId).ConnectionSocket
'Timeout will be 0.5 seconds.
Dim vTimeout As Integer = 500
vConnectionSocket.ReceiveTimeout = vTimeout
'For our little example, we expect all messages to be 1024 bytes or below (arbitrary amount).
Dim vMessageLength As Integer = 1024
'Remember, when dimensioning arrays, the integer specified is the upper bounds, not the length.
Dim vClientMessage(vMessageLength - 1) As Byte
'Receive.
Dim vNumOfBytesReceived As Integer = 0
Try
vNumOfBytesReceived = vConnectionSocket.Receive(vClientMessage, 0, vMessageLength, SocketFlags.None)
Catch ex As Exception
If vConnectionSocket.Connected Then vConnectionSocket.Close()
'MessageBox.Show(String.Format("Timeout occurred before receiving any bytes. Connection with client {0} closed.", vConnectionId))
Exit Sub
End Try
'Did we receive any bytes from the client?
If (vNumOfBytesReceived < 1) OrElse (vConnectionSocket.Connected = False) Then
If vConnectionSocket.Connected Then vConnectionSocket.Close()
'MessageBox.Show(String.Format("Did not receive any bytes. Connection with client {0} closed.", vConnectionId))
Exit Sub
End If
'Trim empty bytes from array.
Dim vTrimmedClientMessage(vNumOfBytesReceived - 1) As Byte
Array.Copy(vClientMessage, vTrimmedClientMessage, vNumOfBytesReceived)
'Return bytes.
Dim vReceivedData As New SentOrReceivedData
With vReceivedData
.ConnectionId = vConnectionId
.RemoteIp = vConnectionSocket.RemoteEndPoint.ToString
.NumOfBytes = vNumOfBytesReceived
.ActualBytes = vTrimmedClientMessage
End With
ReportDoneReceiving_CrossThread(CType(vReceivedData, Object))
'Prepare response message to client.
Dim vResponseMessage As Byte() = Encoding.UTF8.GetBytes("Message Received!")
'Send response.
Try
vConnectionSocket.Send(vResponseMessage)
'Return bytes.
Dim vSentData As New SentOrReceivedData
With vSentData
.ConnectionId = vConnectionId
.RemoteIp = vConnectionSocket.RemoteEndPoint.ToString
.NumOfBytes = vResponseMessage.Length
.ActualBytes = vResponseMessage
End With
ReportDoneSending_CrossThread(CType(vSentData, Object))
Catch ex As Exception
'Report fail or timeout.
If vConnectionSocket.Connected Then vConnectionSocket.Close()
'MessageBox.Show(String.Format("Could not send bytes. Connection with client {0} closed.", vConnectionId))
Exit Sub
End Try
End Sub
Private Sub StopListening()
'We set the stop signal to true so that the listener does not enter another iteration of the loop.
gStopListening = True
'However, since the .NET framework doesn't have any sort of "timeout" property for any of the
'accept methods (e.g. Accept(), BeginAccept(), EndAccept(), etc), the loop will never exit the
'current iteration because it is still waiting on the Accept() line for a connection. So we will
'have to give it what it wants; we will have to send our own connection just so it can accept
'something and break out of the deadlock.
Try
Dim vIp As IPAddress = IPAddress.Parse("127.0.0.1") 'Loop-back IP address (localhost).
Dim vEndPoint As New IPEndPoint(vIp, gPort)
Using vSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
vSocket.Connect(vEndPoint)
'Because we're using a "Using" block, the socket will dispose itself after sending. Part
'of its disposal process is to shut down the socket connection (so we don't have to
'manually tell it to disconnect). This is good b/c the listener will receive TCP
'handshake disconnect info that tells it that the connection has ended, and it will then
'close its side of the socket immediatly, rather than waiting for the Receive() method to
'time out.
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ReportDoneListening_CrossThread()
If Me.InvokeRequired Then
Me.Invoke(New ReportDoneListening_Delegate(AddressOf ReportDoneListening))
Else
ReportDoneListening()
End If
End Sub
Private Delegate Sub ReportDoneListening_Delegate()
Private Sub ReportDoneListening()
btnStartStop.Text = "Start Listening"
End Sub
Private Sub ReportDoneReceiving_CrossThread(ByVal pArg As Object)
If Me.InvokeRequired Then
Me.Invoke(New ReportDoneReceiving_Delegate(AddressOf ReportDoneReceiving), pArg)
Else
ReportDoneReceiving(pArg)
End If
End Sub
Private Delegate Sub ReportDoneReceiving_Delegate(ByVal pArg As Object)
Private Sub ReportDoneReceiving(ByVal pArg As Object)
Dim vConnectionId As Integer = CType(pArg, SentOrReceivedData).ConnectionId
Dim vRemoteIp As String = CType(pArg, SentOrReceivedData).RemoteIp
Dim vNumOfBytesReceived As Integer = CType(pArg, SentOrReceivedData).NumOfBytes
Dim vReceivedBytes As Byte() = CType(pArg, SentOrReceivedData).ActualBytes
For Each vByte As Byte In vReceivedBytes
Dim vLvi As New ListViewItem
With vLvi
'Direction column.
.Text = "RECV -->"
'Connection ID column.
.SubItems.Add(CStr(vConnectionId))
'Client IP column.
.SubItems.Add(vRemoteIp)
'Decimal column.
.SubItems.Add(vByte.ToString)
'Hexidecimal column.
.SubItems.Add(vByte.ToString("X2"))
'Character column.
.SubItems.Add(ChrW(vByte))
End With
With lvwMessages
.Items.Add(vLvi)
.EnsureVisible(.Items.Count - 1)
End With
Next
End Sub
Private Sub ReportDoneSending_CrossThread(ByVal pArg As Object)
If Me.InvokeRequired Then
Me.Invoke(New ReportDoneSending_Delegate(AddressOf ReportDoneSending), pArg)
Else
ReportDoneSending(pArg)
End If
End Sub
Private Delegate Sub ReportDoneSending_Delegate(ByVal pArg As Object)
Private Sub ReportDoneSending(ByVal pArg As Object)
Dim vConnectionId As Integer = CType(pArg, SentOrReceivedData).ConnectionId
Dim vRemoteIp As String = CType(pArg, SentOrReceivedData).RemoteIp
Dim vNumOfBytesSent As Integer = CType(pArg, SentOrReceivedData).NumOfBytes
Dim vSentBytes As Byte() = CType(pArg, SentOrReceivedData).ActualBytes
For Each vByte As Byte In vSentBytes
Dim vLvi As New ListViewItem
With vLvi
'Direction column.
.Text = "<-- SENT"
'Connection ID column.
.SubItems.Add(CStr(vConnectionId))
'Client IP column.
.SubItems.Add(vRemoteIp)
'Decimal column.
.SubItems.Add(vByte.ToString)
'Hexidecimal column.
.SubItems.Add(vByte.ToString("X2"))
'Character column.
.SubItems.Add(ChrW(vByte))
End With
With lvwMessages
.Items.Add(vLvi)
.EnsureVisible(.Items.Count - 1)
End With
Next
End Sub
End Class
Public Structure SocketAndId
Public ConnectionId As Integer
Public ConnectionSocket As Socket
End Structure
Public Structure SentOrReceivedData
Public ConnectionId As Integer
Public RemoteIp As String
Public NumOfBytes As Integer
Public ActualBytes As Byte()
End Structure