/ * ================================================================================================================================================================ ====================== file: Wintalk.cs
Summary: Demonstrate how to create chat programs in .NET
============================================================================================================================================================================================================= ==================== * /
Using system.text; using system.threading; using system.net; using system.net.socks; using system.drawing; using system.windows.form.
Class app {// entry point public static void main (string [] args) {// if the args parse in known Way Run Talker = New Talker Talker (Endpoint, Client); // Pass the Object Reference to a New form Object talkform form = new talkform (talker); // start the talker "talking" talker.start ();
// Run the applications message pump application.run (form);}}
// PARSED Argument Storage Private Static IpendPoint Endpoint; Private Static Bool Client
// Parse command line arguments private static bool ParseArgs (String [] args) {try {if (args.Length == 0) {client = false; endPoint = new IPEndPoint (IPAddress.Any, 5150); return true;} switch (CHAR.TOUPPER (Args [0])) {CASE 'L': INT port = 5150; if (args.length> 1) {port = convert.Toint32 (Args [1]);} endpoint = new IpendPoint (ipaddress.any, port); client = false; break; case 'c': port = 5150; string address = "127.0.0.1"; client = true; if (args.length> 1) {address = args [ 1]; Port = Convert.Toint32 (Args [2]);} endpoint = new iPndPoint (DNS.Resolve (address) .addresslist [0], port); Break; default: showusage (); return false;} catch {showusage (); return false;} return true;
// show sample usage private static void showusage () {MessageBox.show ("Wintalk [Switch] [parameters ...] / n / n" "/ l [port] / t / t - listens ON A Port. Default: 5150 / N " " / c [address] [port] / t - connection one an address and port./n" "eXample server - / n" "Wintalk / L / N / N" "Example Client - / N" "Wintalk / C ServerMachine 5150", "Wintalk Usage");}} // Ui Class for the SampleClass Talkform: Form {Public Talkform (Talker Talker) {// Associate for Method with the THE Talker Object this.talker = talker; talker.notifications = new talker.notificationCallback (HandleTalkerNotification);
// Create a ui elements splitter talksplitter = new splitter (); panel talkpanel = new panel ();
receiveText = new TextBox (); sendText = new TextBox (); // we'll support up to 64k data in our text box controls receiveText.MaxLength = sendText.MaxLength = 65536; statusText = new Label (); // Initialize UI elements receiveText.Dock = DockStyle.Top; receiveText.Multiline = true; receiveText.ScrollBars = ScrollBars.Both; receiveText.Size = new Size (506, 192); receiveText.TabIndex = 1; receiveText.Text = ""; receiveText. WordWrap = false; receiveText.ReadOnly = true; talkPanel.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); talkPanel.Controls.AddRange (new Control [] {sendText, talkSplitter, receiveText}) TalkPanel.size = new size (506, 371); talkpanel.tabindex = 0; talksplitter.dock = dockstyle.top; talksplitter.location = new point (0, 192); ta lkSplitter.Size = new Size (506, 6); talkSplitter.TabIndex = 2; talkSplitter.TabStop = false; statusText.Dock = DockStyle.Bottom; statusText.Location = new Point (0, 377); statusText.Size = new Size (507, 15); statustext.tabindex = 1; statustext.text = "status:";
sendText.Dock = DockStyle.Fill; sendText.Location = new Point (0, 198); sendText.Multiline = true; sendText.ScrollBars = ScrollBars.Both; sendText.Size = new Size (506, 173); sendText.TabIndex = 0; sendText.Text = ""; sendText.WordWrap = false; sendText.TextChanged = new EventHandler (HandleTextChange); sendText.Enabled = false; AutoScaleBaseSize = new Size (5, 13); ClientSize = new Size (507, 392 Controls.addrange (new control [] {statustext, talkpanel}; text = "wintalk";
THIS.ActiveControl = SendText;
// When the app closes, dispose of the talker object protected override void OnClosed (EventArgs e) {if (! Talker = null) {// remove our notification handler talker.Notifications - = new Talker.NotificationCallback (HandleTalkerNotifications); talker. Dispose ();} base.OnClosed (e);} // Handle notifications from the talker object private void HandleTalkerNotifications (Talker.Notification notify, Object data) {switch (notify) {case Talker.Notification.Initialized: break; // Respond to Status Changes Case Talker.Notification.statusChange: Talker.status status = (talker.status) data; statustext.text = string.format ("status: {0}", status); if (status == Talker.status .Connected) {sendtext.enabled = true;} Break; // Respond to received text case talker.notification.received: receiveText.Text = data.ToString (); receiveText.SelectionStart = Int32.MaxValue; receiveText.ScrollToCaret (); break; // Respond to error notifications case Talker.Notification.Error: Close (data.ToString ()); break; // Respond to End Case Talker.Notification.end: MessageBox.show (Data.Tostring (), "Closing Wintalk"); Close (); Break; Default: Close (); Break;}
// Handle text change notifications and send talk private void HandleTextChange (Object sender, EventArgs e) {if (talker = null!) {Talker.SendTalk ((sender as TextBox) .Text);}} // Close with an explanation private Void Close (String Message) {MessageBox.show (Message, "Error!"); Close ();}
// Private Ui Elements Private TextBox ReceiveText; Private TEXTBOX SendText; Private Talker Talker;
// An encapsulation of the Sockets class used for socket chattingclass Talker: IDisposable {// Construct a talker public Talker (IPEndPoint endPoint, bool client) {this.endPoint = endPoint; this.client = client;
Socket = null; reader = null; Writer = NULL;
STATUSTEXT = prevsendtext = prevReceiveText = string.empty;}
// finalize a Talker ~ Talker () {dispose ();
// Dispose of resources and surpress finalization public void dispose () {gc.suppressFinalize (this); if (reader! = Null) {reader.close (); reader = null;} if (writer! = Null) {Writer. Close (); Writer = NULL;} f (socket! = Null) {socket.close (); socket = null;}}
// nested delegat class and matchine Event public delegate void NotificationCallback (Notification Notify, Object Data); Public Event NotificationCallback Notifications
// nested enum for notification {initialized = 1, statuschange, receive, end, error}
// Nested enum for supported states public enum Status {Listening, Connected} // Start up the talker's functionality public void Start () {ThreadPool.QueueUserWorkItem (new WaitCallback (EstablishSocket));}
// Send text to remote connection public void SendTalk (String newText) {String send; // Is this an append if ((prevSendText.Length <= newText.Length) && String.CompareOrdinal (newText, 0, prevSendText, 0, prevSendText .Length) == 0) {string append = newtext.substring (prevsendtext.length); send = string.format ("a {0}: {1}", append.length, append); // OR a Complete Replacement } else {send = string.format ("r {0}: {1}", newText.length, newtext);} // send the data and flush it out} w w (send); Writer.Flush (); // save the text for future commit = newText;
// send a status notification private void setstatus (status status) {this.status = status; notification.statuschange, status;
// Establish a socket connection and start receiving private void EstablishSocket (Object state) {try {// If not client, setup listner if (client!) {Socket listener; try {listener = new Socket (AddressFamily.InterNetwork, SocketType.Stream , Protocoltype.tcp); listener.blocking = true; listener.bind (endpoint); setStatus (status.listening); listener.Listen (0); socket = listener.accept (); listener.close ();} catch SocketException E) {// if there is already a listener on this port try client if (e.errorcode == 10048) {Client = true; endpoint = new iPENDPOINT (DNS.Resolve ("127. 0.0.1 "). AddRESSLIST [0], ENDPOINT.PORT);} else {NOTIFICATIONS (NOTISE.Error," Error Initializing Socket: / N " E.TOSTRING ());}}} // Try a Client Connection IF (client) {socket temp = new socket (addressfamily.internetwork, sockettype.stream, protocoltype.tcp); temp.blocking = true; temp.connect (endpoint); socket = temp;}
// If it all worked out, create stream objects if (socket = null!) {SetStatus (Status.Connected); NetworkStream stream = new NetworkStream (socket); reader = new StreamReader (stream); writer = new StreamWriter (stream) ; Notifications (Notification.Initialized, this);} else {Notifications (Notification.Error, "Failed to Establish Socket");} // Start receiving talk // Note: on w2k and later platforms, the NetworkStream.Read () / / Method Called in ReceiveTalk Will Generate An Exception When // The Remote Connection Closes. We Handle This Case IN Our // Catch Block Below. ReceiveTalk ();
// On Win9x platforms, NetworkStream.Read () returns 0 when // the remote connection closes, prompting a graceful return // from ReceiveTalk () above. We will generate a Notification.End // message here to handle the case and shut . down the remaining // WinTalk instance Notifications (Notification.End, "Remote connection has closed.");} catch (IOException e) {SocketException sockExcept = e.InnerException as SocketException;! if (sockExcept = null && 10054 == sockExcept {NOTIFICATIONS ("Remote Connection Has Closed.");} Else {if (notification.error, "socket error: / n" E.MESSAGE);}} Catch (Exception E) {Notification.Error, "Socket Error: / N" E.MESSAGE);}} // receive chat from remote client private void receverk () { Char [] commandbuffer = new char [20]; char [] onebuffer = new char [1]; int ready = 1; int counter = 0; stringbuilder text = new stringbuilder ();
While (READMODE! = 0) {if (Reader.Read (OneBuffer, 0, 1) == 0) {readMode = 0; CONTINUE;}
Switch (readmode) {case 1: if (counter == comMMandBuffer.Length) {readmode = 0; Continue;} if (OneBuffer [0]! = ':') {CommandBuffer [counter ] = oneBuffer [0];} else {Counter = Convert.Toint32 (New String (CommandBuffer, 1, Counter-1)); if (counter> 0) {readMode = 2; text.length = 0;} else} (CommandBuffer [0] == 'R' ) {Counter = 0; prevReceirtExt = string.empty; notifications (notification.Received, prevreceivetext);}} Break; Case 2: text.append (OneBuffer [0]); if (- counter == 0) {Switch CommandBuffer [0]) {CASE 'R': prevReceiveText = text.ToString (); break; default: prevReceiveText = text.ToString (); break;} readMode = 1; Notifications (Notification.Received, prevReceiveText);} break; default: readMode = 0; continue;}} }
PRIVATE SOCKET Socket;
Private textReader Reader; Bool Client; IpendPoint Endpoint;
Private string prevsendtext; private string statustext;
PRIVATE STATUS;
Microsoft.NET Frameworksdk with this example.