Chat server: Difference between revisions

Content added Content deleted
m (Automated syntax highlighting fixup (second round - minor fixes))
(Dialects of BASIC moved to the BASIC section.)
Line 94: Line 94:
end loop;
end loop;
end Chat_Server;</syntaxhighlight>
end Chat_Server;</syntaxhighlight>

=={{header|BaCon}}==
=={{header|BASIC}}==
==={{header|BaCon}}===
Requires BaCon 4.2 or higher. Clients have to login with an alias and can use the commands 'say' or 'quit'. Notifications are submitted when users enter the chat or leave the chat.
Requires BaCon 4.2 or higher. Clients have to login with an alias and can use the commands 'say' or 'quit'. Notifications are submitted when users enter the chat or leave the chat.
<syntaxhighlight lang="text">DECLARE user$ ASSOC STRING
<syntaxhighlight lang="text">DECLARE user$ ASSOC STRING
Line 131: Line 133:
ENDIF
ENDIF
WEND</syntaxhighlight>
WEND</syntaxhighlight>

==={{header|Visual Basic .NET}}===
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Net.Sockets
Imports System.Text
Imports System.Threading

Module Module1

Class State
Private ReadOnly client As TcpClient
Private ReadOnly sb As New StringBuilder

Public Sub New(name As String, client As TcpClient)
Me.Name = name
Me.client = client
End Sub

Public ReadOnly Property Name As String

Public Sub Send(text As String)
Dim bytes = Encoding.ASCII.GetBytes(String.Format("{0}" & vbCrLf, text))
client.GetStream().Write(bytes, 0, bytes.Length)
End Sub
End Class

ReadOnly connections As New Dictionary(Of Integer, State)
Dim listen As TcpListener
Dim serverThread As Thread

Sub Main()
listen = New TcpListener(Net.IPAddress.Parse("127.0.0.1"), 4004)
serverThread = New Thread(New ThreadStart(AddressOf DoListen))
serverThread.Start()
End Sub

Private Sub DoListen()
listen.Start()
Console.WriteLine("Server: Started server")

Do
Console.Write("Server: Waiting...")
Dim client = listen.AcceptTcpClient()
Console.WriteLine(" Connected")

' New thread with client
Dim clientThread As New Thread(New ParameterizedThreadStart(AddressOf DoClient))

clientThread.Start(client)
Loop
End Sub

Private Sub DoClient(client As TcpClient)
Console.WriteLine("Client (Thread: {0}): Connected!", Thread.CurrentThread.ManagedThreadId)
Dim bytes = Encoding.ASCII.GetBytes("Enter name: ")
client.GetStream().Write(bytes, 0, bytes.Length)

Dim done As Boolean
Dim name As String
Do
If Not client.Connected Then
Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId)
client.Close()
Thread.CurrentThread.Abort() ' Kill thread
End If

name = Receive(client)
done = True

For Each cl In connections
Dim state = cl.Value
If state.Name = name Then
bytes = Encoding.ASCII.GetBytes("Name already registered. Please enter your name: ")
client.GetStream().Write(bytes, 0, bytes.Length)
done = False
End If
Next
Loop While Not done

connections.Add(Thread.CurrentThread.ManagedThreadId, New State(name, client))
Console.WriteLine(vbTab & "Total connections: {0}", connections.Count)
Broadcast(String.Format("+++ {0} arrived +++", name))

Do
Dim text = Receive(client)
If text = "/quit" Then
Broadcast(String.Format("Connection from {0} closed.", name))
connections.Remove(Thread.CurrentThread.ManagedThreadId)
Console.WriteLine(vbTab & "Total connections: {0}", connections.Count)
Exit Do
End If

If Not client.Connected Then
Exit Do
End If

Broadcast(String.Format("{0}> {1}", name, text))
Loop

Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId)
client.Close()
Thread.CurrentThread.Abort()
End Sub

Private Function Receive(client As TcpClient) As String
Dim sb As New StringBuilder
Do
If client.Available > 0 Then
While client.Available > 0
Dim ch = Chr(client.GetStream.ReadByte())
If ch = vbCr Then
' ignore
Continue While
End If
If ch = vbLf Then
Return sb.ToString()
End If
sb.Append(ch)
End While

' pause
Thread.Sleep(100)
End If
Loop
End Function

Private Sub Broadcast(text As String)
Console.WriteLine(text)
For Each client In connections
If client.Key <> Thread.CurrentThread.ManagedThreadId Then
Dim state = client.Value
state.Send(text)
End If
Next
End Sub

End Module</syntaxhighlight>

=={{header|C}}==
=={{header|C}}==
C has no built-in networking functions, but the POSIX library does provide some low-level networking functions. The functions of interest relating to sockets include ''bind'', ''listen'', ''select'', ''accept'', ''read'', ''write'' and ''close''.
C has no built-in networking functions, but the POSIX library does provide some low-level networking functions. The functions of interest relating to sockets include ''bind'', ''listen'', ''select'', ''accept'', ''read'', ''write'' and ''close''.
Line 3,659: Line 3,799:
set ::cmap {}; # Dictionary mapping nicks to channels
set ::cmap {}; # Dictionary mapping nicks to channels
vwait forever; # Run event loop</syntaxhighlight>
vwait forever; # Run event loop</syntaxhighlight>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System.Net.Sockets
Imports System.Text
Imports System.Threading


Module Module1

Class State
Private ReadOnly client As TcpClient
Private ReadOnly sb As New StringBuilder

Public Sub New(name As String, client As TcpClient)
Me.Name = name
Me.client = client
End Sub

Public ReadOnly Property Name As String

Public Sub Send(text As String)
Dim bytes = Encoding.ASCII.GetBytes(String.Format("{0}" & vbCrLf, text))
client.GetStream().Write(bytes, 0, bytes.Length)
End Sub
End Class

ReadOnly connections As New Dictionary(Of Integer, State)
Dim listen As TcpListener
Dim serverThread As Thread

Sub Main()
listen = New TcpListener(Net.IPAddress.Parse("127.0.0.1"), 4004)
serverThread = New Thread(New ThreadStart(AddressOf DoListen))
serverThread.Start()
End Sub

Private Sub DoListen()
listen.Start()
Console.WriteLine("Server: Started server")

Do
Console.Write("Server: Waiting...")
Dim client = listen.AcceptTcpClient()
Console.WriteLine(" Connected")

' New thread with client
Dim clientThread As New Thread(New ParameterizedThreadStart(AddressOf DoClient))

clientThread.Start(client)
Loop
End Sub

Private Sub DoClient(client As TcpClient)
Console.WriteLine("Client (Thread: {0}): Connected!", Thread.CurrentThread.ManagedThreadId)
Dim bytes = Encoding.ASCII.GetBytes("Enter name: ")
client.GetStream().Write(bytes, 0, bytes.Length)

Dim done As Boolean
Dim name As String
Do
If Not client.Connected Then
Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId)
client.Close()
Thread.CurrentThread.Abort() ' Kill thread
End If

name = Receive(client)
done = True

For Each cl In connections
Dim state = cl.Value
If state.Name = name Then
bytes = Encoding.ASCII.GetBytes("Name already registered. Please enter your name: ")
client.GetStream().Write(bytes, 0, bytes.Length)
done = False
End If
Next
Loop While Not done

connections.Add(Thread.CurrentThread.ManagedThreadId, New State(name, client))
Console.WriteLine(vbTab & "Total connections: {0}", connections.Count)
Broadcast(String.Format("+++ {0} arrived +++", name))

Do
Dim text = Receive(client)
If text = "/quit" Then
Broadcast(String.Format("Connection from {0} closed.", name))
connections.Remove(Thread.CurrentThread.ManagedThreadId)
Console.WriteLine(vbTab & "Total connections: {0}", connections.Count)
Exit Do
End If

If Not client.Connected Then
Exit Do
End If

Broadcast(String.Format("{0}> {1}", name, text))
Loop

Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId)
client.Close()
Thread.CurrentThread.Abort()
End Sub

Private Function Receive(client As TcpClient) As String
Dim sb As New StringBuilder
Do
If client.Available > 0 Then
While client.Available > 0
Dim ch = Chr(client.GetStream.ReadByte())
If ch = vbCr Then
' ignore
Continue While
End If
If ch = vbLf Then
Return sb.ToString()
End If
sb.Append(ch)
End While

' pause
Thread.Sleep(100)
End If
Loop
End Function

Private Sub Broadcast(text As String)
Console.WriteLine(text)
For Each client In connections
If client.Key <> Thread.CurrentThread.ManagedThreadId Then
Dim state = client.Value
state.Send(text)
End If
Next
End Sub

End Module</syntaxhighlight>
=={{header|Wren}}==
=={{header|Wren}}==
An embedded solution using a C host since Wren has no built in support for either networking or multi-threading.
An embedded solution using a C host since Wren has no built in support for either networking or multi-threading.