Probleme: client IRC multi-threading

Signaler
Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006
-
Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006
-
Quand je me connecte a un serveur irc, je recois un peu de reponse du serveur puis j ai une erreur qui me dis que un thread ne peux etre execute depuis un autre thread:

public class cPage
    {
        public static TabControl _tabControl;
        public static System.Collections.ArrayList _List = new System.Collections.ArrayList();
        private TabPage _page;
        private RichTextBox _text;
        private TextBox _input;

        private Socket _socket;
        private IPEndPoint _endPoint;
        private IPAddress _ipAddress;
        private byte[] _buffer = new byte[256];

        public cPage(string toUrl, int toPort)
        {
            _page = new TabPage(toUrl);
            _page.UseVisualStyleBackColor = true;
            _tabControl.TabPages.Add(_page);
            _text = new RichTextBox();
            _text.ReadOnly = true;
            _text.Dock = DockStyle.Fill;
            _text.Text = "Bienvenue...\n";
            _page.Controls.Add(_text);
            _input = new TextBox();
            _input.Dock = DockStyle.Bottom;
            _page.Controls.Add(_input);

            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try 
            {
                _ipAddress = IPAddress.Parse(toUrl);
            }
            catch (Exception e) 
            {
                string error = e.Message;
                IPHostEntry entry =  Dns.GetHostEntry(toUrl);
                IPAddress[] addr = entry.AddressList;
                _ipAddress = addr[0];

            }
            try
            {
                _endPoint = new IPEndPoint(_ipAddress, toPort);
                _socket.Blocking = false;
                AsyncCallback onconnect = new AsyncCallback(OnConnect);
                _socket.BeginConnect(_endPoint, onconnect, _socket);
                MessageBox.Show("Connected");
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message,"Constructor");
            }
        }

        private void OnConnect(IAsyncResult ar)
        {
            Socket sock = (Socket)ar.AsyncState;
            try
            {
                if (sock.Connected)
                {
                    SetupReceiveCallback(sock);
                }
                else
                {
                    MessageBox.Show("Impossible de se connecter au serveur.","OnConnect");
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "OnConnect");
            }
        }

        private void SetupReceiveCallback(Socket sock)
        {
            try
            {
                AsyncCallback receive = new AsyncCallback(OnReceiveData);
                sock.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, OnReceiveData, sock);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message,"SetupReceiveCallback");
            }
        }

        private void OnReceiveData(IAsyncResult ar)
        {
            Socket sock = (Socket)ar.AsyncState;
            try
            {
                int nBytes = sock.EndReceive(ar);
                if (nBytes > 0)
                {
                    _text.Text += Encoding.ASCII.GetString(_buffer, 0, nBytes);
                    SetupReceiveCallback(sock);
                }
                else if (nBytes == 0)
                {
                    MessageBox.Show("EOF");
                }
                else
                {
                    MessageBox.Show("Connection timed out");
                    sock.Shutdown(SocketShutdown.Both);
                    sock.Close();
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message,"OnReceiveData");
            }
        }
    }

(necessite la creation d'une instance de la classe et du _TabControl)
http://skurcey.f2o.org/fcss/FCS.php
A voir également:

5 réponses

Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006

Ok, j ai resolu mon probleme, mais maintenant je ne sais pas comment recuperer la liste des channels, je dois ouvrir une nouvelle connection ou qulque chose comme ca?
Je n'ai reussi a avoir une reponse du serveur apres mon send.
namespace Irc
{
public partial class w_main : Form
{
public w_main()
{
InitializeComponent();
cPage._tabControl = main_tabcontrol;
cPage test = new cPage("irc.voidzero.com", 6667);
}
}

public class cPage
{
public static TabControl _tabControl;
public static System.Collections.ArrayList _List = new System.Collections.ArrayList();
private TabPage _page;
private RichTextBox _text;
private TextBox _input;
private string _url;
private int _port;

private Socket _socket;
private IPEndPoint _endPoint;
private IPAddress _ipAddress;
private byte[] _buffer = new byte[256];
private byte[] _sendbuf = new byte[256];

public cPage(string toUrl, int toPort)
{
_page = new TabPage(toUrl);
_page.UseVisualStyleBackColor = true;
_tabControl.TabPages.Add(_page);
_text = new RichTextBox();
_text.ReadOnly = true;
_text.Dock = DockStyle.Fill;
_text.Text = "Bienvenue...\n";
_page.Controls.Add(_text);
_input = new TextBox();
_input.Dock = DockStyle.Bottom;
_input.KeyPress += new KeyPressEventHandler(_input_KeyPress);
_page.Controls.Add(_input);
_url = toUrl;
_port = toPort;

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
_ipAddress = IPAddress.Parse(toUrl);
}
catch (Exception e)
{
string error = e.Message;
IPHostEntry entry = Dns.GetHostEntry(toUrl);
IPAddress[] addr = entry.AddressList;
_ipAddress = addr[0];

}
try
{
_socket.Blocking = false;
_socket.BeginConnect(new IPEndPoint(_ipAddress, toPort), new AsyncCallback(AsyncConnect), _socket);

}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

void _input_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
Send(_input.Text);
_input.Text = "";
}
}

private void AsyncConnect(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
sock.EndConnect(ar);
_text.Text += "Connection a " + _url + ":" + _port + ", ok.\n";
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(AsyncReceive), _socket);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

private void AsyncReceive(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
int nBytes = sock.EndReceive(ar);
if (nBytes > 0)
{
_text.Text += Encoding.ASCII.GetString(_buffer);
Buffer.SetByte(_buffer, 0, 0);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

public void Send(string msg)
{
_sendbuf = Encoding.ASCII.GetBytes(msg);
_socket.BeginSend(_sendbuf, 0, _sendbuf.Length, SocketFlags.None, new AsyncCallback(AsyncSend), _socket);
_text.Text += msg + "\n";
}

private void AsyncSend(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
int send = sock.EndSend(ar);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
http://skurcey.f2o.org/fcss/FCS.php
Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006

Apparement, je ne peux utiliser l'ajout d'un texte a partir d'un thread, comment dois je faire? j'ai cru comprendre que je devrais utiliser append et invoke mais j avoue, je suis largue...

http://skurcey.f2o.org/fcss/FCS.php
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
49
Salut,
Pour connaitre l'utilisation d'Invoke, vas voir ce tutorial



Mx
MVP C#
Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006

Merci, javais pas saisi au debut que Invoke etait une methode des objets de la GUI, ca marche maintenant.. @+
http://skurcey.f2o.org/fcss/FCS.php
Messages postés
12
Date d'inscription
mercredi 7 avril 2004
Statut
Membre
Dernière intervention
9 mars 2006

QUand j'essaye en local, ca marche bien mais quand j'essaye en me connectant a un serveur irc, je n'obtiend pas de reponse a la commande NICK ou USER, alors qu'avec telnet, oui.
Si jamais, voila mon code:

namespace Irc
{
public partial class w_main : Form
{
public w_main()
{
InitializeComponent();
cPage._tabControl = main_tabcontrol;
cPage test = new cPage("irc.voidzero.com", 6667);

}

private void main_toolitem_ok_Click(object sender, EventArgs e)
{
if (main_toolitem_url.Text != string.Empty)
{
cPage page = new cPage(main_toolitem_url.Text, int.Parse(main_toolitem_port.Text));
}
else
{
cPage page = new cPage(int.Parse(main_toolitem_port.Text));
}
}

private void main_toolitem_help_Click(object sender, EventArgs e)
{
MessageBox.Show("Pour lancer un onglet client:\n URL + port\nPour un onglet serveur:\n Ne pas mettre d'URL et ne pas oubliez d'enlever les ports du firewall.");
}
}

public class cPage
{
public static TabControl _tabControl;
public static int _bufLength = 512;
public static System.Collections.ArrayList _list = new System.Collections.ArrayList();

private bool _srv = false;
private TabPage _page;
private RichTextBox _output;
private TextBox _input;

private Socket _socket;
private byte[] _bufout = new byte[_bufLength];
private byte[] _bufin = new byte[_bufLength];

private System.Collections.ArrayList _clientList;

public cPage(string toUrl, int toPort)
{
IPAddress ip;
newPage(toUrl, toPort);
_output.Text = "Connecting to: "+toUrl+":"+toPort.ToString()+"\n";
_srv = false;

try
{
try
{
ip = IPAddress.Parse(toUrl);
}
catch (Exception e)
{
string error = e.Message;
IPAddress[] addresses = Dns.GetHostAddresses(toUrl);
ip = addresses[0];
}

IPEndPoint endpoint = new IPEndPoint(ip, toPort);
try
{
AsyncCallback callback = new AsyncCallback(OnConnect);
_socket.BeginConnect(endpoint, OnConnect, _socket);
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Constructor");

}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Constructor Error");
}
}

public cPage(int toPort)
{
try
{
newPage("Serveur", toPort);
_output.Text = "New server on port:" + toPort.ToString()+"\n";
_srv = true;

IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, toPort);
_socket.Bind(endpoint);
_socket.Listen(32);
_clientList = new System.Collections.ArrayList();
Accept();
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Constructor(Serveur)");
RemoveTab();
}
}

private void newPage(string toUrl,int toPort)
{
_page = new TabPage(toUrl + ":" + toPort.ToString());
_page.UseVisualStyleBackColor = true;
_tabControl.TabPages.Add(_page);
_output = new RichTextBox();
_output.ReadOnly = true;
_output.Dock = DockStyle.Fill;
_page.Controls.Add(_output);
_input = new TextBox();
_input.Dock = DockStyle.Bottom;
_page.Controls.Add(_input);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Blocking = false;
_input.KeyPress += new KeyPressEventHandler(_input_KeyPress);
}

private delegate void DelegateAddMessage(string msg);
private void AddMessage(string msg)
{
_output.AppendText(msg);
_output.AppendText("\r\n");
}

private delegate void DelegateRemoveTab();
private void RemoveTab()
{
_tabControl.TabPages.Remove(_page);
// DESTRUCTEUR DE CLASSE ICI
} // DESTRUCTEUR DE CLASSE ICI, ????probleme

void _input_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
Send(_input.Text);
_input.Text = "";
}
}

private void OnConnect(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
sock.EndConnect(ar);
if (sock.Connected)
{
_output.Invoke(new DelegateAddMessage(AddMessage), "Connection Ok!!!");
Receive(sock);
}
else
{
_tabControl.Invoke(new DelegateRemoveTab(RemoveTab));
MessageBox.Show("Erreur, ne peux se connecter", "Connection Error");
}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "OnConnect");
_tabControl.Invoke(new DelegateRemoveTab(RemoveTab));
}
}

private void Receive(Socket sock)
{
AsyncCallback callback = new AsyncCallback(OnReceive);
sock.BeginReceive(_bufin, 0, _bufin.Length, SocketFlags.None, callback, sock);
}

private void OnReceive(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
int nBytes = sock.EndReceive(ar);
if (nBytes > 0)
{
string msg = Encoding.ASCII.GetString(_bufin);
_output.Invoke(new DelegateAddMessage(AddMessage), msg);
_bufin = new byte[_bufLength];
Receive(sock);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "OnReceive");
}

}

private void Send(string msg)
{
try
{
AddMessage("<::>" + msg);
//_output.Text += ">" + msg + "\n";
_bufout = Encoding.ASCII.GetBytes(msg);
if (!_srv)
{
AsyncCallback callback = new AsyncCallback(OnSend);
_socket.BeginSend(_bufout, 0, _bufout.Length, SocketFlags.None, OnSend, _socket);
}
else
{
foreach (cClient client in _clientList)
{
AsyncCallback callback = new AsyncCallback(OnSend);
client._socket.BeginSend(_bufout, 0, _bufout.Length, SocketFlags.None, OnSend, client._socket);
}
}
}
catch (Exception e)
{
MessageBoxButtons b = MessageBoxButtons.YesNo;
switch (MessageBox.Show(e.Message+"\n\nVoulez-vous supprimmer l'onglet?", "Error", b))
{
case DialogResult.Yes:
RemoveTab();
break;
}
}
_bufout = new byte[_bufLength];

}

private void OnSend(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
sock.EndSend(ar);

}

private void Accept()
{
AsyncCallback callback = new AsyncCallback(OnAccept);
_socket.BeginAccept(callback, null);
}

private void OnAccept(IAsyncResult ar)
{
cClient client = new cClient();
client._socket = _socket.EndAccept(ar);
Receive(client._socket);
_clientList.Add(client);
_output.Invoke(new DelegateAddMessage(AddMessage), "Nouveau Client\n");
Accept();
}

}

public class cClient
{
public Socket _socket;
public byte[] _bufin = new byte[512];
}
}