Library code snippets
A Chat Client/Server Program for C#
By Michael H, published on 26 Jan 2004
Here's some code for a chat server, and an accompanying client program.
The client:
using System.IO;
using System.Net;
using System;
using System.Threading;
using N = System.Net;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel;
using System.Runtime.InteropServices;
class TalkUser {
static Form talk;
static N.Sockets.TcpClient TC;
[DllImport("kernel32.dll")]
private static extern void ExitProcess(int a);
public static void Main() {
talk = new Form();
talk.Text = "TalkUser - The OFFICIAL TalkServ Client";
talk.Closing += new CancelEventHandler(talk_Closing);
talk.Controls.Add(new TextBox());
talk.Controls[0].Dock = DockStyle.Fill;
talk.Controls.Add(new TextBox());
talk.Controls[1].Dock = DockStyle.Bottom;
((TextBox)talk.Controls[0]).Multiline = true;
((TextBox)talk.Controls[1]).Multiline = true;
talk.WindowState = FormWindowState.Maximized;
talk.Show();
((TextBox)talk.Controls[1]).KeyUp += new KeyEventHandler(key_up);
TC = new N.Sockets.TcpClient();
TC.Connect("IP OF A SERVER HERE",4296);
Thread t = new Thread(new ThreadStart(run));
t.Start();
while(true) {
Application.DoEvents();
}
}
private static void talk_Closing(object s, CancelEventArgs e) {
e.Cancel = false;
Application.Exit();
ExitProcess(0);
}
private static void key_up(object s,KeyEventArgs e) {
TextBox TB = (TextBox)s;
if(TB.Lines.Length>1) {
StreamWriter SW = new StreamWriter(TC.GetStream());
SW.WriteLine(TB.Text);
SW.Flush();
TB.Text = "";
TB.Lines = null;
}
}
private static void run() {
StreamReader SR = new StreamReader(TC.GetStream());
while(true) {
Application.DoEvents();
TextBox TB = (TextBox)talk.Controls[0];
TB.AppendText(SR.ReadLine()+"\r\n");
TB.SelectionStart = TB.Text.Length;
}
}
}
And the server:
using System.IO;
using System.Net;
using System;
using System.Threading;
using N = System.Net;
using System.Collections;
class TalkServ {
System.Net.Sockets.TcpListener server;
public static Hashtable handles;
public static Hashtable handleByConnect;
public static void Main() {
TalkServ TS = new TalkServ();
}
public TalkServ() {
handles = new Hashtable(100);
handleByConnect = new Hashtable(100);
server = new System.Net.Sockets.TcpListener(4296);
while(true) {
server.Start();
if(server.Pending()) {
N.Sockets.TcpClient connection = server.AcceptTcpClient();
Console.WriteLine("Connection made");
BackForth BF = new BackForth(connection);
}
}
}
public static void SendToAll(string name,string msg) {
StreamWriter SW;
ArrayList ToRemove = new ArrayList(0);
N.Sockets.TcpClient[] tc = new N.Sockets.TcpClient[TalkServ.handles.Count];
TalkServ.handles.Values.CopyTo(tc,0);
for(int i=0;i<tc.Length;i++) {
try {
if(msg.Trim()==""||tc[i]==null)
continue;
SW = new StreamWriter(tc[i].GetStream());
SW.WriteLine(name + ": " + msg);
SW.Flush();
SW = null;
} catch(Exception e44) { e44 = e44;
string g = (string) TalkServ.handleByConnect[tc[i]];
TalkServ.SendSysMsg("** " + g + " ** HAS LEFT US.");
TalkServ.handles.Remove(g);
TalkServ.handleByConnect.Remove(tc[i]);
}
}
}
public static void SendSysMsg(string msg) {
StreamWriter SW;
ArrayList ToRemove = new ArrayList(0);
N.Sockets.TcpClient[] tc = new N.Sockets.TcpClient[TalkServ.handles.Count];
TalkServ.handles.Values.CopyTo(tc,0);
for(int i=0;i<tc.Length;i++) {
try {
if(msg.Trim()==""||tc[i]==null)
continue;
SW = new StreamWriter(tc[i].GetStream());
SW.WriteLine(msg);
SW.Flush();
SW = null;
} catch(Exception e44) { e44 = e44;
TalkServ.handles.Remove(TalkServ.handleByConnect[tc[i]]);
TalkServ.handleByConnect.Remove(tc[i]);
}
}
}
}//end of class TalkServ
class BackForth {
N.Sockets.TcpClient client;
System.IO.StreamReader SR;
System.IO.StreamWriter SW;
string handle;
public BackForth(System.Net.Sockets.TcpClient c) {
client = c;
Thread t = new Thread(new ThreadStart(init));
t.Start();
}
private string GetHandle() {
SW.WriteLine("What is your handle? ");
SW.Flush();
return SR.ReadLine();
}
private void run() {
try {
string l = "";
while(true) {
l = SR.ReadLine();
TalkServ.SendToAll(handle,l);
}
} catch(Exception e44) { Console.WriteLine(e44); }
}
private void init() {
SR = new System.IO.StreamReader(client.GetStream());
SW = new System.IO.StreamWriter(client.GetStream());
SW.WriteLine("WELCOME TO TalkServ! Be Nice!");
//SW.WriteLine("What is your handle? ");
//SW.Flush();
handle = GetHandle();
while(TalkServ.handles.Contains(handle)) {
SW.WriteLine("ERR - Handle already exists!");
handle = GetHandle();
}
TalkServ.handles.Add(handle,client);
TalkServ.handleByConnect.Add(client,handle);
TalkServ.SendSysMsg("** " + handle + " ** HAS JOINED US.");
SW.WriteLine("Now Talking.....\r\n-------------------------------");
SW.Flush();
Thread t = new Thread(new ThreadStart(run));
t.Start();
}
}
Related articles
Related discussion
-
Buy cheap Xanax overnight. Cheap Xanax. Overnight delivery of Xanax in US no prescription needed. Cheapest Xanax.
by asleymar (0 replies)
-
Buy Soma online without a prescription. Soma drug no prescription. How to get Soma prescription. Soma cod accepted.
by asleymar (0 replies)
-
Cheap online order Fioricet. Cheap discount Fioricet. Offshore Fioricet online. How to buy Fioricet online without a prescription.
by asleymar (0 replies)
-
Buy Ambien no visa without prescription. Not expensive Ambien prescriptions. Ambien no rx. Cod delivery Ambien.
by asleymar (0 replies)
-
Tramadol without doctor rx. Buy Tramadol over the counter cod overnight. Cheap Tramadol cod delivery. Buy Tramadol from mexico online.
by asleymar (0 replies)
Related podcasts
-
Object-Oriented Programming in Ruby
In this episode, I talk with Scott Bellware about object-oriented programming in Ruby, and Ruby's object model. This is taken from a private conversation, and the audio quality suffers at times. Much thanks to Scott for allowing this to be released.This episode of the Alt.NET Podcast is bro...
Maybe someone on this thread can stop me from pulling the rest of my limited hair out.
I have something running that is similar to that posted above (threads w/ TCPClient, etc) and something that should be REALLY simple is seemingly impossible. I'm attempting to display a command prompt that will have the user input directly to the right of it (easy, eh?) . The code to do this is: // Display command prompt public static void CommandPrompt(string username) { StreamWriter StrWrite; TcpClient client;
The issue is that the Flush() isn't actually causing the > to display as expected .. it will only actually display that to the client after the next WriteLine is issued OR if I terminate the > with a \r. Both things defeat the purpose since I WANT the input to be next to the >, not below it.
Thoughts? Or am I not explaining this well?
!--removed tag-->Public domain in the USA. As close as possible elsewhere (as there are countries that don't recognize public domain, apparently). Attribution welcome, but not necessary. Job offers in the Chicago area also welcome (hint hint :P ). Just to clear that up. Wouldn't have thought such a simple program would need it.
I wrote this when I was 16 in high school so a friend and I could chat during Comp Sci class using Telnet to connect to the server on my home computer; I wrote the client program later for kicks. I'd highly recommend rewriting your own chat server from scratch; once you've done that once... IRC protocol (or at least something with multiple rooms) is not that difficult (besides server-to-server connections ;).
For those who have used this program for class projects/homework, I would strongly suggest that you write your own chat server / client. Or even a simple web server. There are certain patterns evident in any server (ie a thread per connection, tables for usernames vs. sockets, etc). Use it as an example, don't just copy code (even though you are perfectly free to do so).
I'm currently working on a programming language (and compiler) that is based in part on C#/Java, called Telesto at telesto.sf.net . (end plug)
!--removed tag-->To stop the while loop lockups (100% CPU issue), you'll need to make the following changes:
Client: while(true) { Application.DoEvents(); } Becomes: Application.Run();
And
Server: if(server.Pending()) { N.Sockets.TcpClient connection = server.AcceptTcpClient(); Console.WriteLine("Connection made"); BackForth BF = new BackForth(connection);
} Becomes: N.Sockets.TcpClient connection = server.AcceptTcpClient(); Console.WriteLine("Connection made"); BackForth BF = new BackForth(connection);
On another note, I can't find any copyright information on this. Is there any documentation on usage rights?
!--removed tag-->Thank you for this article. This is exactly what i need for my purposes. I've converted your server code into a Windows Service and runing it on our dedicated server. Everything works better than OK, except one frustrating thing. Both server and client when running are taking all the 100% of CPU usage. System is slowing down dramaticly and i can't release a client with a perfomance like that.
Is there any way to speed up both client and server?
Best regards!
This was an excellent working example for me - showed all the major working parts in a simple and clear way.
For those of you communicating with a Flash client you might want to use:
SW.Write("<some message>\0");
instead of SW.WriteLine("<some message>");
but that's just Flash - it needs Zero terminated strings.
Good job dude!![Big Smile [:D]](/emoticons/emotion-2a.gif)
Clicking a button of that programs form .... should run this "TalkUser" program.
Pls tell me how to do it.
This thread is for discussions of A Chat Client/Server Program for C#.