Chat server: Difference between revisions

Line 352:
}</lang>
 
=={{header|CoffeeScriptC#|C sharp}}==
<lang csharp>using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
namespace ChatServer {
class State {
private TcpClient client;
private StringBuilder sb = new StringBuilder();
 
public string Name { get; }
 
public State(string name, TcpClient client) {
Name = name;
this.client = client;
}
 
public void Add(byte b) {
sb.Append((char)b);
}
 
public void Send(string text) {
var bytes = Encoding.ASCII.GetBytes(string.Format("{0}\r\n", text));
client.GetStream().Write(bytes, 0, bytes.Length);
}
}
 
class Program {
static TcpListener listen;
static Thread serverthread;
static Dictionary<int, State> connections = new Dictionary<int, State>();
 
static void Main(string[] args) {
listen = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 4004);
serverthread = new Thread(new ThreadStart(DoListen));
serverthread.Start();
}
 
private static void DoListen() {
// Listen
listen.Start();
Console.WriteLine("Server: Started server");
 
while (true) {
Console.WriteLine("Server: Waiting...");
TcpClient client = listen.AcceptTcpClient();
Console.WriteLine("Server: Waited");
 
// New thread with client
Thread clientThread = new Thread(new ParameterizedThreadStart(DoClient));
clientThread.Start(client);
}
}
 
private static void DoClient(object client) {
// Read data
TcpClient tClient = (TcpClient)client;
 
Console.WriteLine("Client (Thread: {0}): Connected!", Thread.CurrentThread.ManagedThreadId);
byte[] bytes = Encoding.ASCII.GetBytes("Enter name: ");
tClient.GetStream().Write(bytes, 0, bytes.Length);
 
string name = string.Empty;
bool done = false;
do {
if (!tClient.Connected) {
Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId);
tClient.Close();
Thread.CurrentThread.Abort(); // Kill thread.
}
 
name = Receive(tClient);
done = true;
 
if (done) {
foreach (var cl in connections) {
var state = cl.Value;
if (state.Name == name) {
bytes = Encoding.ASCII.GetBytes("Name already registered. Please enter your name: ");
tClient.GetStream().Write(bytes, 0, bytes.Length);
done = false;
}
}
}
} while (!done);
 
connections.Add(Thread.CurrentThread.ManagedThreadId, new State(name, tClient));
Console.WriteLine("\tTotal connections: {0}", connections.Count);
Broadcast(string.Format("+++ {0} arrived +++", name));
 
do {
string text = Receive(tClient);
if (text == "/quit") {
Broadcast(string.Format("Connection from {0} closed.", name));
connections.Remove(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("\tTotal connections: {0}", connections.Count);
break;
}
 
if (!tClient.Connected) {
break;
}
Broadcast(string.Format("{0}> {1}", name, text));
} while (true);
 
Console.WriteLine("Client (Thread: {0}): Terminated!", Thread.CurrentThread.ManagedThreadId);
tClient.Close();
Thread.CurrentThread.Abort();
}
 
private static string Receive(TcpClient client) {
StringBuilder sb = new StringBuilder();
do {
if (client.Available > 0) {
while (client.Available > 0) {
char ch = (char)client.GetStream().ReadByte();
if (ch == '\r') {
//ignore
continue;
}
if (ch == '\n') {
return sb.ToString();
}
sb.Append(ch);
}
}
 
// Pause
Thread.Sleep(100);
} while (true);
}
 
private static void Broadcast(string text) {
Console.WriteLine(text);
foreach (var oClient in connections) {
if (oClient.Key != Thread.CurrentThread.ManagedThreadId) {
State state = oClient.Value;
state.Send(text);
}
}
}
}
}</lang>
 
=={{header|CoffeeScript}}==
This is ported from the JavaScript version. The tool js2coffee got me a mostly working version, and then I manually converted JS-style classes to CS "classic-style class" syntax.
 
1,452

edits