Chat server: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) 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. |