komunikace přes TCP   otázka

C#, Algoritmy, I/O operace

Dobrý den,

potřeboval bych řešit komunikaci mezi 2 aplikacemi prostřednictvím TCP protokolu a jsem z toho jelen. Jedna aplikace bude tedy server, druhá bude klient... aplikace by si měly vzájemně povídat - budou na sebe posílat nějaké řetězce (xml, ale to je jedno). Četl jsem zdejší článek, koukal jsem na netu na různé příklady a nějak to pořád moc nechápu. Rád bych to udělal co nejjednodušeji. Klient i server by měl neustále naslouchat a pokud příjde řetězec, měl by jej zpracovat. Obě dvě strany by zároveň měly po stisknutí butonu zaslat na protějšek řetězec.

Zkoušel jsem různá řešení, ale povedlo se mi vždy maximálně zaslat řetězec na protějšek a tím to haslo, pak už to nešlo ani tam ani zpět.

posledni zkušební verze serveru:

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        private static TcpListener tcpListener;
        private static Socket soc;
        private static Stream s;
        private string result = "";

        public Form1()
        {
            InitializeComponent();

            tcpListener = new TcpListener(44444);
            tcpListener.Start();
            
            Thread thread = new Thread(new ThreadStart(Listen));
            thread.IsBackground = true;
            thread.Start();
        }

        public void Listen()
        {
            while (true)
            {
                soc = tcpListener.AcceptSocket();
                try
                {
                    s = new NetworkStream(soc);
                    StreamReader sr = new StreamReader(s);
                    StreamWriter sw = new StreamWriter(s);
                    sw.AutoFlush = true;
                    sw.WriteLine("Připojil si se k serveru");
                    while (true)
                    {
                        result = sr.ReadToEnd();
                        Vypis();
                    }
                    s.Close();
                }
                catch (Exception ex)
                {

                }
                soc.Close();
            }
        }

        private void Vypis()
        {
            if (!InvokeRequired)
            {
                textBox1.Text += result + Environment.NewLine;
            }
            else
            {
                Invoke(new ThreadStart(Vypis));
            }
        }
    

        private void button2_Click(object sender, EventArgs e)
        {
            //Byte[] SendTheseBytes = Encoding.ASCII.GetBytes(textBox2.Text);
            //s.Write(SendTheseBytes, 0, SendTheseBytes.Length);
            StreamWriter sw = new StreamWriter(s);
            sw.AutoFlush = true;
            sw.WriteLine("Připojil si se k serveru");
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }
    }
}

poslední zkušební řešení klienta:

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        TcpClient tcpClient = new TcpClient("127.0.0.1", 44444);
        Stream s;

        
        public Form1()
        {
            InitializeComponent();

            s = tcpClient.GetStream();
            StreamReader sr = new StreamReader(s);
            textBox2.Text = sr.ReadLine();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            StreamWriter sw = new StreamWriter(s);
            sw.AutoFlush = true;
            while (true)
            {
                sw.Write(textBox1.Text);
            }
        }

       
    }
}

Děkuji za radu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nikdo??

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Mohlo by to být tím, že nezapisujete do NetworkStreamu přímo, ale přes jiné streamy. Podívejte se na příklady k TcpListeneru a TcpClientu na MSDN. Pokud to nebude fungovat tak můžete použít WCF, je to nesrovnatelně jednodušší než čisté TCP.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Bohužel to musím řešit právě přímo prostřednictvím TCP. Škoda, že zde není článek, který se přímo této problematice věnuje. docela bych byl rád, kdybych v tom měl jasno.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Možná je to tím, že StreamReader a StreamWriter po sobě ten vnitřní stream zavřou, což bohužel není to, co zrovna potřebujete. Až budu mít trochu času, zkusím to pořádně projet a dám vědět.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No zkuste to předělat na ty NetworkStreamy jak jsem radil. To WCF může pracovat také přes TCP, je to pouze nadstavba nad obecnými komunikačními protokoly.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak nakonec jsem nastudoval 2 a 3 kapitolu zdejšího seriálu o kreslící tabuli a podle toho se mi povedlo udělat jak server tak klienta a oba dělají přesně to co mají. Super.

Díky moc.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ale zajímalo by mě stejně trochu více vše kolem TCP komunikace. Těch přístupů k problému je více, zajímaly by mě rozdíly a tak (streamwriter, streamreader, stream, networkstream, socket, tcpclient a tak...). To by byl krásný článek :-)

Díky za skvělý web.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ono na tom není nic složitého, buď k tomu přistupujete WinApi způsobem pomocí TcpClientu nebo Socketu, nebo si uděláte NetworkStream z toho a pak k tomu přistupujete jako ke streamu a můžete používat standardní funkce a třídy pro práci se streamy (vč kompresních nebo šifrovaních "mezistreamů") :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak mám tedy klienta i server podle místního článku, vše chodí, jak má, paráda. Nyní však ošetřuji spojení - pro případ, že se druhá strana ukončí.

U serveru je to jednoduché, tam, pokud je v proceduře CtiData vyvolaná vyjímka, tak zavřu tcpClienta a opět spustím Listener.

Problém mám s klientskou řástí, myslel jsem, že to opět budu řešit vyjímkou a spustím timer, ve kterém se budu pokoušet znovu připojit:

void reconnectTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
              tcpClient.BeginConnect("127.0.0.1", 44444, Pripojit, null);
            }
            catch

        }

public void Pripojit(IAsyncResult at)
        {
            try
            {
                reconnectTimer.Enabled = false;
                tcpClient.EndConnect(at);
                s = tcpClient.GetStream();
                s.BeginRead(buffer, 0, BUFFER_SIZE, CtiData, null);
            }
            catch

        }

ale nějak mi to nefunguje.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback