[Mono-list] assertion g_utf8_validate failed
Mario Fuentes
mario@gnome.cl
Fri, 12 Nov 2004 11:44:51 -0300
--=-Q3Awd2kKiiwpw6VkCLwl
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
El vie, 12-11-2004 a las 06:51 -0500, Jonathan Pryor escribió:
[...]
> Instead, use GLib.Timeout.Add (with a small timeout) or
> Gtk.ThreadNotify. You can pass each of these a delegate, which will be
> invoked from the GTK+ UI thread, so you don't need to worry about
> locking/unlocking the application, cleaning up your code, and
> maintaining your sanity.
>
Thanks, I rewrite my sample, and now *seems* it's OK. I attach my
sample for to receive feedback. :D
> - Jon
Bye guys.
--
Mario Fuentes
http://primate.gnome.cl/~mario
mailto:mario@gnome.cl
--=-Q3Awd2kKiiwpw6VkCLwl
Content-Disposition: attachment; filename=Chat.cs
Content-Type: text/x-csharp; name=Chat.cs; charset=utf-8
Content-Transfer-Encoding: 7bit
// Mario Fuentes <mario@gnome.cl>
// Compile: mcs -pkg:gtk-sharp Chat.cs
namespace Samples {
using System;
using System.Text;
using System.Collections;
using System.Net;
using SNS = System.Net.Sockets;
using System.IO;
using System.Threading;
using Gtk;
public delegate void NetEventHandler (NetEventType type, string text);
public enum NetEventType
{
Connected,
NewMessage,
}
public class Net
{
#region Packet
internal class Packet {
internal byte [] buffer;
internal SNS.Socket socket;
internal Packet (int size, SNS.Socket sock)
{
buffer = new byte[size];
socket = sock;
}
}
#endregion
// Default Port
const int DEFAULT_PORT = 9999;
// Notification Event
public event NetEventHandler NetEvent = null;
// Flags
bool started = false;
bool isConnected = false;
public bool IsConnected { get { return isConnected; } }
bool isServer = false;
bool done = false;
// UserName
string userName;
// Host Name
string host = null;
// Socket
SNS.Socket sock = null;
SNS.Socket srvSock = null;
Queue inbox;
byte [] buffer = null;
Packet pack = null;
// Instance a server
public Net ()
{
isServer = true;
Init ();
}
// Instance a client
public Net (string host)
{
this.host = host;
Init ();
}
void Init ()
{
userName = System.Environment.UserName;
inbox = new Queue ();
GLib.Timeout.Add (100, new GLib.TimeoutHandler (TimeoutFunc));
CreateSocket ();
}
// Check for new messages
bool TimeoutFunc ()
{
if (isConnected)
{
if (!started)
{
if (NetEvent != null)
NetEvent (NetEventType.Connected, null);
started = true;
}
if (inbox.Count > 0)
{
string str = inbox.Dequeue () as string;
if (NetEvent != null)
NetEvent (NetEventType.NewMessage, str);
}
}
return !done;
}
void CreateSocket ()
{
IPAddress ipAddress;
if (isServer)
ipAddress = IPAddress.Any;
else
ipAddress = Dns.Resolve (host).AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint (ipAddress, DEFAULT_PORT);
sock = new SNS.Socket (SNS.AddressFamily.InterNetwork,
SNS.SocketType.Stream,
SNS.ProtocolType.Tcp);
if (isServer)
{
sock.Bind (ipEndPoint);
sock.Listen (1);
sock.BeginAccept (new AsyncCallback (OnConnectCallback), sock);
}
else
{
sock.BeginConnect (ipEndPoint,
new AsyncCallback (OnConnectCallback), sock);
}
}
void OnConnectCallback (IAsyncResult ar)
{
SNS.Socket socket = (SNS.Socket) ar.AsyncState;
SNS.Socket serverSock = null;
Console.Write ("OnConnectCallback.... ");
if (isServer)
{
serverSock = socket.EndAccept (ar);
srvSock = serverSock;
if (serverSock.Connected == false)
return;
socket.Close ();
}
else
{
socket.EndConnect (ar);
if (socket.Connected == false)
return;
}
Console.WriteLine ("Connected!");
isConnected = true;
SNS.Socket s = (isServer) ? serverSock : socket;
s.Blocking = false;
WaitForData (s);
}
void WaitForData (SNS.Socket s)
{
pack = new Packet (256, s);
s.BeginReceive (pack.buffer, 0, pack.buffer.Length,
SNS.SocketFlags.None, new AsyncCallback (this.OnDataReceive), pack);
}
void OnDataReceive (IAsyncResult ar)
{
Packet packet = ar.AsyncState as Packet;
int len = packet.socket.EndReceive (ar);
string strRec = Encoding.UTF8.GetString (packet.buffer);
inbox.Enqueue (strRec);
WaitForData (packet.socket);
}
void OnDataSend (IAsyncResult ar)
{
string text = ar.AsyncState as String;
inbox.Enqueue (text);
}
public void Send (string str)
{
string strSend = userName + "> " + str;
byte [] buf = Encoding.UTF8.GetBytes (strSend);
Packet packet = new Packet (0, pack.socket);
packet.socket.BeginSend (buf, 0, buf.Length,
SNS.SocketFlags.None, new AsyncCallback (OnDataSend), strSend);
}
}
public class Chat : Window
{
// GUI
Entry entHost;
Button btnConnect;
Button btnCreate;
ScrolledWindow scrollChat;
TextView textChat;
Entry entChat;
// Network
Net net;
public Chat () : base (WindowType.Toplevel)
{
// Setup window properties
this.Title = "Chat";
this.BorderWidth = 12;
this.DeleteEvent += OnDeleteEvent;
// Add a vertical box
VBox box = new VBox (false, 6);
// Pack box on the window
this.Add (box);
// Create a table for packing controls
Table table = new Table (3, 2, false);
table.RowSpacing = 3;
table.ColumnSpacing = 6;
// Pack table on the box
box.PackStart (table, false, false, 0);
// Pack a label on the table
table.Attach (new Label ("Host:"), 0, 1, 0, 1);
// Create and pack a entre con the table, for get hostname from user
entHost = new Entry ();
table.Attach (entHost, 1, 2, 0, 1);
// A button for try connect to "Host"
btnConnect = new Button ("Connect");
btnConnect.Clicked += OnBtnConnectClicked;
table.Attach (btnConnect, 2, 3, 0, 1);
// A button for create a server (listen for a user)
btnCreate = new Button ("Create a server!");
btnCreate.Clicked += OnBtnCreateClicked;
table.Attach (btnCreate, 0, 3, 1, 2);
// A scrolled window container for pack the textview
scrollChat = new ScrolledWindow ();
scrollChat.ShadowType = ShadowType.In;
// Pack on the box
box.PackStart (scrollChat);
// TextView for view send/receive text
textChat = new TextView ();
textChat.Editable = false;
textChat.WrapMode = WrapMode.Word;
// Pack text into scroll
scrollChat.Add (textChat);
// A entry for user text
entChat = new Entry ();
entChat.Activated += OnEntChatActivated;
box.PackStart (entChat, false, false, 0);
// Show the windows and all widgets/controls contained
this.ShowAll ();
}
void AppendText (string text)
{
textChat.Buffer.Text += text;
textChat.Buffer.Text += System.Environment.NewLine;
scrollChat.Vadjustment.Value = scrollChat.Vadjustment.Upper;
}
void SetSensitive (bool b)
{
entHost.Sensitive = b;
btnConnect.Sensitive = b;
btnCreate.Sensitive = b;
}
void ConnectTo (string host)
{
if (host == null)
net = new Net ();
else
net = new Net (entHost.Text);
net.NetEvent += OnNetEvent;
SetSensitive (false);
}
void OnNetEvent (NetEventType t, string s)
{
switch (t)
{
case NetEventType.Connected:
AppendText ("** Connected **");
break;
case NetEventType.NewMessage:
AppendText (s);
break;
}
}
#region Callbacks from the GUI
void OnDeleteEvent (object o, DeleteEventArgs args)
{
// Disconnect
// TODO
// Stop GTK loop
args.RetVal = true;
Application.Quit ();
}
void OnBtnConnectClicked (object o, EventArgs args)
{
if (entHost.Text == String.Empty)
{
AppendText ("** Host is empty **");
return;
}
ConnectTo (entHost.Text);
}
void OnBtnCreateClicked (object o, EventArgs args)
{
ConnectTo (null);
}
void OnEntChatActivated (object o, EventArgs args)
{
if (entChat.Text == String.Empty)
return;
if ((net == null) || !net.IsConnected)
{
AppendText ("** You aren't connected **");
return;
}
net.Send (entChat.Text);
entChat.Text = String.Empty;
}
#endregion
public static void Main (string [] args)
{
Application.Init ();
new Chat ();
Application.Run ();
}
}
}
--=-Q3Awd2kKiiwpw6VkCLwl--