none
Problem avec TcpListener/TcpClient ; VS.NET C# EXPRESS 2005 RRS feed

  • Question

  • Le client initie une connexion vers le serveur sur port 81

    Pour tester, il faut redéfinir les variables pour le port et l'adresse du serveur ex:127.0.0.1

    Le client envoit une chaine "READYTOSEND"

    Le serveur reçoit la chaîne

    Le serveur est censé envoyer "RTS-OK"

    Le client bloque en lecture !!!!!!!!!

    Le débuggueur VS bloque sur la lecture depuis le client.

    Si on supprime le code de lecture (reponse du serveur) dans le client, ça va mieux, mais ce n'est pas l'objectif, mon objectif est un aller/retour ! J'ai déjà fait ça sur WINdows CE.net mais je ne retrouve plus le source, donc faut que je réinvente ma roue, Smile)))))

     

    MERCI !

     

     

    THREAD CLIENT :

    Thread t2 = null;

    private void clientThread()

    {

    // Attention à logguer avec log2 (log depuis thread!)

    /// ...

    try

    {

    // Create a TcpClient.

    // Note, for this client to work you need to have a TcpServer

    // connected to the same address as specified by the server, port

    // combination.

    Int32 port = iPortDistant;

    TcpClient client = new TcpClient(strServeurDistant, port);

    string message = "READYTOSEND";

    // Get a client stream for reading and writing.

    NetworkStream stream = client.GetStream();

    // Send the message to the connected TcpServer.

    for (int k = 0; k < message.Length; k++)

    stream.WriteByte( (byte) message[k] );

    log2("Sent: " + message);

    log2("Now receiving server response.");

    log2("CANREAD=" + stream.CanRead);

    log2("DATAAVAILABLE=" + stream.DataAvailable);

     

    // BLOCAGE!!!

    // Receive the TcpServer.response.

    string reponse = string.Empty;

    int r = 0;

    while(r != -1)

    {

    r = stream.ReadByte(); // Juste pour tester

    if (r != -1) reponse = reponse + (char)r;

    }

    log2("Received : " + reponse);

    // Close everything.

    stream.Close();

    client.Close();

    }

    catch (ArgumentNullException ea)

    {

    log2("ArgumentNullException: " + ea.Message);

    }

    catch (SocketException es)

    {

    log2("SocketException: " + es.Message);

    }

    }

     

     

    THREAD SERVEUR :

     

    private void threadServeur()

    {

    try

    {

    slog("Démarrage du serveur en cours.");

    /// ...

    TcpListener server = null;

    try

    {

    // Set the TcpListener on port 7575.

    Int32 port = iPortLocal;

    IPAddress localAddr = IPAddress.Parse("0.0.0.0");

    //server = new TcpListener(port);

    server = new TcpListener(localAddr, port);

    // Start listening for client requests.

    server.Start();

    // Enter the listening loop.

    while (true)

    {

    slog("Waiting for a connection... ");

    // Perform a blocking call to accept requests.

    // You could also user server.AcceptSocket() here.

    TcpClient client = server.AcceptTcpClient();

    slog("A client is connected !");

    slog("Receiving commands from client.");

    // Get a stream object for reading and writing

    NetworkStream stream = client.GetStream();

    int i = 0;

    while (i != -1)

    {

    i = stream.ReadByte();

    if (i != -1) slog("Received : " + i.ToString() + " / " + (char)i);

    else slog("No more data on stream.");

    }

    //TESTER

    slog("More data ? : " + stream.DataAvailable);

    slog("CANWRITE=" + stream.CanWrite);

    slog("Sending response.");

    string stosend = "RTS-OK";

    for (int k = 0; k < stosend.Length; k++)

    {

    try

    {

    slog("Sending 1 byte : " + stosend[k]);

    stream.WriteByte( (byte) stosend[k] );

    }

    catch (Exception e) { slog("Exception : " + e.Message); }

    }

    // Shutdown and end connection

    client.Close();

    }

    }

    catch (SocketException e)

    {

    slog("SocketException: " + e.Message);

    }

    finally

    {

    // Stop listening for new clients.

    server.Stop();

    }

    }

    catch (Exception e)

    {

    slog("Exception lors du démarrage du serveur : " + e.Message);

    }

    }

     

     

    jeudi 29 mai 2008 06:58

Réponses

Toutes les réponses

  •  

    Salut ! Désolé pour mon mal-élevé-isme, mais comme ma connexion est lente et mauvaise je tape toujours trop vite et je bypasse trop souvent les greetings... ;(

     

    Merci pour les links. J'ai pu trouver une alternative, tout recoder au niveau socket... Comme je ne suis pas élitiste, je vous balance tout le code source, si quelqu'un en a besoin... Ca sera et cela a déjà été le cas héhé...

     

    Maintenant mon problème est que je n'arrive pas à redémarrer le serveur sur le même port (blocage sur bind).

     

    Je vais creuser les liens...

     

    AU REVOIR!! TCHAO! ASTALAVISTA Smile)))

     

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

    using System.Net.Sockets;

    using System.Net;

    using System.Threading;

    namespace DualCom

    {

    public partial class frmMain : Form

    {

    public frmMain()

    {

    InitializeComponent();

    }

    int iPortDistant = 81;

    string strServeurDistant = "127.0.0.1";

    int iPortLocal = 81;

    bool bAutoStart = true;

    bool bHideGUI = false;

    // Outil de communication entre deux postes à travers internet

    // Développé dans un objectif d'utilisation en tant qu'outil système ou de communication entre

    // deux personnes uniquement sur internet (du moins dans la version initiale).

    // Peut-on écrire "PEER TO PEER privé ?" Wink

    // Une utilisation par une personne seulement est possible : Une instance de DualCom sur un PC

    // connecté à internet, et une deuxième instance sur un deuxième PC (à l'autre bout du monde)

    // contrôlée totalement depuis le premier PC.

    private void frmMain_Load(object sender, EventArgs e)

    {

    this.txtHoteDistant.Text = strServeurDistant;

    this.txtPortDistant.Text = iPortDistant.ToString();

    this.txtPortLocal.Text = iPortLocal.ToString();

    // false = ne pas logguer l'état demandé

    // Priorité est donnée à l'état invisible

    if (getHideGUIState(false)) { this.Hide(); }

    if (getAutoStartState(false)) { this.demarrerServeur(); }

    getHideGUIState(true);

    getAutoStartState(true);

    }

     

    Socket server = null;

    Socket client = null;

    bool bstopserver = false;

    private void threadServeur()

    {

    // logguer avec slog2!!

    server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    IPAddress addr = new IPAddress(new byte[] { 0, 0, 0, 0 });

    IPEndPoint ep = new IPEndPoint(addr, iPortLocal); ;

    server.Bind(ep);

    server.Listen(25);

    while (bstopserver == false)

    {

    client = server.Accept();

    sendToClient(client, "hello");

    string rec = receiveFromClient(client);

    }

    bstopserver = false;

    client.Close();

    server.Shutdown(SocketShutdown.Both);

    server.Close();

    }

    Socket client2 = null;

    private void clientThread()

    {

    // Attention à logguer avec log2 (log depuis thread!)

    client2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    client2.Connect(strServeurDistant, iPortDistant);

    string rec = receiveFromServer(client2);

    sendToServer(client2, "hi, how are you?");

    }

     

    private void btnDeconnecter_Click(object sender, EventArgs e)

    {

    arreterClient();

    }

    Thread t1 = null; // thread serveur

    Thread t2 = null; // thread client

    private void demarrerServeur()

    {

    slog("** demarrerServeur");

    refreshData();

    t1 = new Thread(new ThreadStart(threadServeur));

    t1.Start();

    }

    private void arreterServeur()

    {

    slog("** arreterServeur");

    bstopserver = true;

    t1.Abort();

    }

    // Si nécessaire, non utilisé pour l'instant

    private void arreterClient()

    {

    log("** arreterClient");

    try

    {

    t2.Abort();

    }

    catch (Exception e)

    {

    log("Exception : " + e.Message);

    }

    }

     

    private void sendToClient(Socket client, string strtosend)

    {

    slog("** sendToClient : [" + strtosend + "]");

    byte[] buffer = new byte[256];

    buffer.Initialize();

    for (int i = 0; i < strtosend.Length; i++)

    bufferIdea = (byte)strtosendIdea;

    client.Send(buffer);

    }

    private string receiveFromClient(Socket client)

    {

    slog("** receiveFromClient");

    byte[] buffer = new byte[256];

    buffer.Initialize();

    buffer.Initialize();

    client.Receive(buffer);

    string strreceived = "";

    int j = 0;

    while (buffer[j] != 0)

    strreceived += (char)buffer[j++];

    slog("Received from client : [" + strreceived + "]");

    return strreceived;

    }

    private string receiveFromServer(Socket client)

    {

    log2("** receiveFromServer");

    byte[] buffer = new byte[256];

    client.Receive(buffer);

    string resp = "";

    int i = 0;

    while (bufferIdea != 0)

    resp += (char)buffer[i++];

    log2("Received from server : [" + resp + "]");

    return resp;

    }

    private void sendToServer(Socket client, string strtosend)

    {

    log2("** sendToServer + [" + strtosend + "]");

    byte[] buffer = new byte[256];

    buffer.Initialize();

    for (int j = 0; j < strtosend.Length; j++)

    buffer[j] = (byte)strtosend[j];

    client.Send(buffer);

    }

    // Affecte les nouvelles valeurs éventuellement saisies sur l'interface

    private void refreshData()

    {

    iPortDistant = Int32.Parse(txtPortDistant.Text);

    iPortLocal = Int32.Parse(txtPortLocal.Text);

    strServeurDistant = txtHoteDistant.Text;

    }

     

     

    private bool getAutoStartState(bool bLog) {

    if (bLog) log("bAutoStart=" + bAutoStart);

    return bAutoStart; }

    private bool getHideGUIState(bool bLog) {

    if (bLog) log("bHideGUI=" + bHideGUI);

    return bHideGUI; }

    // Logs utilisateur

    private void log(string str) { txtUserLog.AppendText(DateTime.Now+" : "+str+"\r\n"); }

    // Logs depuis thread client

    private void log2(string str) { SetText2(DateTime.Now + " : " + str + "\r\n"); }

    // Logs concernant le fonctionnement du serveur local.

    // Passage forcé par une méthode déléguée car le serveur est basé sur un thread.

    private void slog(string str) { SetText(DateTime.Now + " : " + str + "\r\n"); }

    // Pour logguer normalement les logs serveur (non à partir de thread).

    private void slog2(string str) { txtServerLog.AppendText(DateTime.Now + " : " + str + "\r\n"); }

    // This delegate enables asynchronous calls for setting

    // the text property on a TextBox control.

    delegate void SetTextCallback(string text);

    delegate void SetTextCallback2(string text);

     

    private void SetText(string text)

    {

    // InvokeRequired required compares the thread ID of the

    // calling thread to the thread ID of the creating thread.

    // If these threads are different, it returns true.

    if (this.txtServerLog.InvokeRequired)

    {

    SetTextCallback d = new SetTextCallback(SetText);

    this.Invoke(d, new object[] { text });

    }

    else

    this.txtServerLog.AppendText(text);

    }

    private void SetText2(string text)

    {

    // InvokeRequired required compares the thread ID of the

    // calling thread to the thread ID of the creating thread.

    // If these threads are different, it returns true.

    if (this.txtUserLog.InvokeRequired)

    {

    SetTextCallback2 d = new SetTextCallback2(SetText2);

    this.Invoke(d, new object[] { text });

    }

    else

    this.txtUserLog.AppendText(text);

    }

    // Connexion au serveur DualCom distant

    private void btnConnecter_Click(object sender, EventArgs e)

    {

    refreshData();

    t2 = new Thread(new ThreadStart(clientThread));

    t2.Start();

    }

    private void btnDemarrerServeur_Click(object sender, EventArgs e)

    {

    refreshData();

    demarrerServeur();

    }

    private void btnArretServeur_Click(object sender, EventArgs e)

    {

    arreterServeur();

    }

     

    }

    }

     

     

     

     

    • Proposé comme réponse Morpheus53 jeudi 7 mai 2009 18:46
    jeudi 29 mai 2008 10:25
  • Bonjour à tous, j'aurais une question pour Skynalyzer2008 :
    Serait-il possible que tu puisses me mettre ton dossier de ton application, car j'aimerais pouvoir l'étudier et l'approfondir ?

    Merci,
    jeudi 7 mai 2009 18:53