using System; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; using Gtk; class Mconvers { public static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine ("Usage: mconvers [hostname] [port]"); return; } Application.Init (); new Convers (args); Application.Run (); } } public class Convers : Window { private TcpClient client; private Statusbar sb; private bool connected = false; private NetworkStream ns; private StreamReader reader; private StreamWriter writer; private Thread receive; private TextBuffer b; private TextView tv; private Entry e; private ScrolledWindow sw; private ThreadNotify notify; private Button btn; private string data; private string hostname; private int port; public Convers (string[] s) : base ("mconvers") { this.SetDefaultSize (500, 300); this.DeleteEvent += new DeleteEventHandler (OnMyWindowDelete); VBox vb = new VBox (false, 0); this.Add (vb); sw = new ScrolledWindow (); sw.ShadowType = ShadowType.In; sw.HscrollbarPolicy = PolicyType.Never; sw.VscrollbarPolicy = PolicyType.Always; vb.PackStart (sw, true, true, 0); tv = new TextView (); b = tv.Buffer; tv.Editable = false; tv.WrapMode = WrapMode.Char; tv.CursorVisible = false; tv.CanFocus = false; sw.Add (tv); e = new Entry (); e.Activated += new EventHandler (OnText); vb.PackStart (e, false, true, 0); e.GrabFocus (); sb = new Statusbar (); vb.PackStart (sb, false, true, 0); notify = new ThreadNotify (new ReadyEvent (ready)); hostname = s[0]; port = Convert.ToInt16 (s[1]); this.Shown += new EventHandler (connect); this.ShowAll (); } private void sbupdate (string s) { sb.Pop (1); sb.Push (1, s); } static void OnMyWindowDelete (object o, DeleteEventArgs args) { Application.Quit (); } private void OnText (object o, EventArgs args) { if (connected) { writer.WriteLine (e.Text + "\n"); writer.Flush (); } e.DeleteText (0, -1); } private void ready () { TextMark EndMark; b.Insert (b.EndIter, data); b.Insert (b.EndIter, "\r\n"); EndMark = b.CreateMark ("end", b.EndIter, false); tv.ScrollToMark (EndMark, 0.4, true, 0.0, 1.0); b.DeleteMark (EndMark); } private void ReceiveChat () { try { try { data = ""; while (connected && (data = reader.ReadLine ()) != null) { notify.WakeupMain (); Thread.Sleep (50); } } catch (IOException e) { sbupdate ("IOException: " + e.Message); } finally { sbupdate ("Connection closed"); connected = false; } } catch (ThreadAbortException) { Thread.ResetAbort (); sbupdate ("ReadThread Aborted"); } } private void connect (object obj, EventArgs args) { try { IPHostEntry hostinfo = Dns.GetHostByName (hostname); client = new TcpClient(); client.NoDelay = true; client.ReceiveTimeout = 600000; client.SendTimeout = 600000; client.Connect (hostinfo.AddressList[0], port); ns = client.GetStream(); reader = new StreamReader (ns); writer = new StreamWriter (ns); connected = true; } catch (Exception e) { sbupdate ("Connection refused"); } if (connected) { try { sbupdate ("Connected"); receive = new Thread (new ThreadStart (ReceiveChat)); receive.IsBackground = true; receive.Start (); } catch (Exception e) { receive.Abort (); reader.Close (); connected = false; sbupdate ("Error logging in"); } } } }