Síťové připojení – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Síťové připojení – .NET – Fórum – Programujte.comSíťové připojení – .NET – Fórum – Programujte.com

 

RePRO0
Super člen
5. 7. 2010   #1
-
0
-

Zdravím,
- událost btnSendToServer_Click funguje naprosto v pohodě a odešle serveru zprávu (tento Button, na který je událost při kliku spuštěna je na hlavním formuláři)

- událost btnPiskvorky_Click nefunguje (pokaždé když kliknu na Button, který je ve třídě (HerniPlocha.cs), tak mi to hodí, že Stream stream = klient.GetStream(); je NULL. Víceméně se uzavře (spadne spojení) a já nevím proč - (The operation is not allowed on non-connected sockets))

To znamená, že zpráva 1 se odešle, kdežto zpráva 2 ne.

Pomůže mi někdo? Měl někdo podobný problém někdy? Prosím jenom hodnotné a užitečné odpovědi, díky moc.

using System;

using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace Piškvorky
{
public partial class Klient : Form
{
// proměnná port typu řetězec
string port;
// proměnná IP typu řetězec
string IP;
// vytvoříme klienta
TcpClient klient = new TcpClient();
// pomocná proměnná plocha
HerniPlocha plocha;
// koncový bod serveru
IPEndPoint koncovyBod;

public Klient()
{
// inicializace komponent
InitializeComponent();
// nastavíme label na výchozí pozici
labelStav.Text = " Nepřipojeno k serveru ";
// vytvoříme hrací plochu
plocha = new HerniPlocha();

}

// metoda, která se snaží připojit k serveru
public void pripojit()
{
try
{
// načteme port
port = textBoxPort.Text;
// načteme IP
IP = textBoxIP.Text;
// nejprve vyparsujeme IP adresu
IPAddress novaIP = IPAddress.Parse(IP);
// a převede port z čísla na string
int novyPort = Convert.ToInt16(port, 10);
// koncový bod
koncovyBod = new IPEndPoint(novaIP, novyPort);
// a zkusíme se připojit na server :-)
klient.Connect(koncovyBod);
// nastavíme viditelnost tlačítka odpojeno na true
btnOdpojit.Enabled = true;
// nastavíme viditelnost tlačítka připojeno na false
btnPripojit.Enabled = false;
// zobrazíme hrací pole
plocha.zobrazPlochu();
// přidáme plochu na formulář (jedná se o Groupbox)
this.Controls.Add(plocha);

if (klient.Connected)
{
try
{
labelStav.Text = " Připojeno ";
}
catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
}

// chyba při spojení na server
catch (SocketException s)
{
MessageBox.Show(s.Message.ToString());
}

// špatná IP nebo Port
catch (FormatException)
{
MessageBox.Show(" Špatně zadaná IP adresa nebo číslo portu ");
}

// špatně zadaný Port (přetečení - více jak 16bitové)
catch (OverflowException)
{
MessageBox.Show(" Špatně zadaný port ");
}
}

// metoda, která se odpojí od serveru
void odpojit()
{
// odpojíme klienta od serveru
klient.Close();
// nastavíme viditelnost tlačítek
btnOdpojit.Enabled = false;
btnPripojit.Enabled = true;
// a smažeme plochu z tohoto formuláře
this.Controls.Remove(plocha);

if (!klient.Connected)
{
try
{
labelStav.Text = " Nepřipojeno k serveru ";
}
catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
}

public void poslatServeru(string zprava)
{
try
{
Stream stream = klient.GetStream();
StreamWriter sw = new StreamWriter(stream);
sw.Write(zprava);
}

catch (SocketException s)
{
MessageBox.Show(s.Message);
}
}

public void testPripojeni()
{
if (!klient.Connected)
{
try
{
labelStav.Text = " Nepřipojeno k serveru ";
}

catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}

else
{
try
{
labelStav.Text = " Připojeno k serveru ";
}

catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
}

private void btnPripojit_Click(object sender, EventArgs e)
{
pripojit();
}

private void brnOdpojit_Click(object sender, EventArgs e)
{
odpojit();
}

private void btnSendToServer_Click(object sender, EventArgs e)
{
poslatServeru(" Zpráva 1 ");
testPripojeni();
}

public void btnPiskvorky_Click(object sender, EventArgs e)
{
poslatServeru(" Zpráva 2 ");
testPripojeni();
}
}
}

Nahlásit jako SPAM
IP: 83.240.104.–
Software: C; C++; C#; Pascal; Delphi; Java Webdesign: PHP; MySQL; CSS; jQuery; Ajax; Javascript; OOP
liborb
~ Redaktor
+18
Guru
7. 7. 2010   #2
-
0
-

Určitě bych měl několik výhrad k tomu zdrojovému kódu, ale ty necháme na potom :). Takhle na pohled tam nevidím důvod, proč by to nemělo něco dělat (trochu tuším, ale ...), takže bude potřeba si to zkusit. Dej sem, prosím tě, kompletní projekt a uvidíme, kde je problém.

Nahlásit jako SPAM
IP: 85.207.166.–
RePRO0
Super člen
7. 7. 2010   #3
-
0
-

Tak tady by měly být TY dvě třídy. Budu rád, když se to vyřeší. Stoprocentně vím, že tam plno věcí řeším zbytečně a špatně.
Jinak mi samozřejmě veškeré výhrady a chyby napiš - budu rád. Chci to mít co nejelegantnější a čisté. Prostě vhodné řešení, díky všem.

using System;

using System.Drawing;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;

namespace Piškvorky
{
public partial class Klient : Form
{
// třídní proměnná port (port, na který se bude Klient připojovat)
private string port;
// třídní proměnná IP (IP adresa, na kterou se bude Klient připojovat)
private string IP;
// vytvoříme klienta
private TcpClient klientSoket = new TcpClient();
// pomocná proměnná plocha (naše Herní plocha)
private HerniPlocha plocha;

// konstruktor
public Klient()
{
// inicializace všech komponent
InitializeComponent();
// vytvoříme Herní plochu
plocha = new HerniPlocha();
}

// metoda, která se snaží připojit klienta k serveru
public void pripojit()
{
try
{
// načteme port z textového pole
port = textBoxPort.Text;
// načteme IP adresu z textového pole
IP = textBoxIP.Text;
// vyparsujeme IP adresu
IPAddress novaIP = IPAddress.Parse(IP);
// převedeme port ze stringu na číslo
int novyPort = Convert.ToInt16(port, 10);
// koncový bod na který se připojujeme
IPEndPoint koncovyBod = new IPEndPoint(novaIP, novyPort);
// a zkusíme se připojit na server :-)
klientSoket.Connect(koncovyBod);
// nastavíme viditelnost tlačítka odpojeno na true
btnOdpojit.Enabled = true;
// nastavíme viditelnost tlačítka připojeno na false
btnPripojit.Enabled = false;
// zobrazíme hrací pole
plocha.zobrazitPlochu();
// přidáme plochu na hlavní Formulář (jedná se o Groupbox)
this.Controls.Add(plocha);

// test připojení (výpis do Labelu)
testPripojeni();
}

// chyba při spojení na server
catch (SocketException s)
{
MessageBox.Show(s.Message.ToString());
}

// špatná IP nebo Port
catch (FormatException)
{
MessageBox.Show(" Špatně zadaná IP adresa nebo číslo portu ");
}

// špatně zadaný Port (přetečení - více jak 16bitové)
catch (OverflowException)
{
MessageBox.Show(" Špatně zadaný port ");
}
}

// metoda, odpojení od serveru (nefunkční - klientSoket.Close koliduje)
public void odpojit()
{
// odpojíme klienta od serveru
klientSoket.Close();
// nastavíme viditelnost tlačítka odpojit na false
btnOdpojit.Enabled = false;
// nastavíme viditelnost tlačítka připojit na true
btnPripojit.Enabled = true;
// a smažeme plochu z tohoto formuláře
this.Controls.Remove(plocha);

// test připojení (výpis do Labelu)
testPripojeni();
}

// metoda, která zašle serveru zprávu
public void poslatZpravuServeru(string zprava)
{
try
{
// náš stream
Stream stream = klientSoket.GetStream();
// vytvoříme si nového Writera (zapisovače)
StreamWriter sw = new StreamWriter(stream);
// a Writer zapíše zprávu do streamu
sw.Write(zprava);
}

// soket chyba (chyba přenosu)
catch (SocketException s)
{
MessageBox.Show(s.Message);
}
}

// metoda, která kontroluje připojení (výpis do Labelu)
public void testPripojeni()
{
if (!klientSoket.Connected)
{
try
{
labelStav.Text = " Nepřipojeno k serveru ";
}

catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
else
{
try
{
labelStav.Text = " Připojeno k serveru ";
}

catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
}

// událostní procedura pro připojení
private void btnPripojit_Click(object sender, EventArgs e)
{
pripojit();
}

// událostní procedura pro odpojení
private void btnOdpojit_Click(object sender, EventArgs e)
{
odpojit();
}

// událostní procedura (Button na formuláři)
private void btnSendToServer_Click(object sender, EventArgs e)
{
poslatZpravuServeru(" Zpráva 1 ");
testPripojeni();
}

// událostní procedura (Buttony na herní ploše)
public void btnPiskvorky_Click(object sender, EventArgs e)
{
poslatZpravuServeru(" Zpráva 2 ");
testPripojeni();
}
}

class HerniPlocha : GroupBox
{
// třídní proměnná tlačítko
private Button btn;
// třídní proměnná klient
private Klient klient;
// ---- PARAMETRY HERNÍHO POLE ----
private int nPocetNaRadek = 12;
private int nPocetNaSloupec = 12;
private int nSirka = 16;
private int nVyska = 16;
private int x, y;
// --------------------------------

// konstruktor
public HerniPlocha()
{
// nastavíme velikost hracího pole na formuláři
this.Size = new Size(200, 200);
// nastavíme pozici hracího pole na formuláři
this.Location = new Point(20, 160);
}

// metoda, která zobrazí hrací pole
public void zobrazitPlochu()
{
// vytvoříme klienta
klient = new Klient();
for (int i = 0; i < nPocetNaRadek; ++i)
{
x = 0;
for (int j = 0; j < nPocetNaSloupec; ++j)
{
btn = new Button();
btn.Size = new Size(15, 15);
btn.Location = new Point(x, y);
btn.BackColor = Color.WhiteSmoke;
btn.FlatStyle = FlatStyle.Flat;
btn.Click += new EventHandler(klient.btnPiskvorky_Click);
x += nSirka;

this.Controls.Add(btn);
}
y += nVyska;
}
}
}
}


Nahlásit jako SPAM
IP: 83.240.104.–
Software: C; C++; C#; Pascal; Delphi; Java Webdesign: PHP; MySQL; CSS; jQuery; Ajax; Javascript; OOP
liborb
~ Redaktor
+18
Guru
8. 7. 2010   #4
-
0
-

Tak chyba, co tě zajímá, je tady:



// metoda, která zobrazí hrací pole
public void zobrazitPlochu()
{
// vytvoříme klienta
klient = new Klient(); // <- nutno smazat


Ty si totiž vytvoříš formulář, ve kterém se připojíš - inicializuješ si instanci spojení. Ale před vytvořením hracího pole zalozíš nového klienta, který má samozřejmě svoje instanční proměnné. Řešením je předat referenci na vytvořený formulář do instance třídy HerníPole, třebas přes konstruktor:


plocha = new HerniPlocha(this);

// ...

public HerniPlocha(Klient klient)
{
// mimo jine si ulozis referenci
this.klient = klient;

// ... to cos tam mel



A teď jdna připomínka ke kódu. Co si myslel tímto?:


if (!klientSoket.Connected)
{
try
{
labelStav.Text = " Nepřipojeno k serveru ";
}
catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}
else
{
try
{
labelStav.Text = " Připojeno k serveru ";

}
catch (Exception)
{
labelStav.Text = " Neznámý stav ";
}
}


Asi mělo být if (!klientSoket.Connected) ve sekci try, ne?

A jinak řešení přes buttony je možné (aj se to pokus dotáhnout do konce), ale asi budeš mít problémy se zobrazením kolečko/křížek. Vykreslení herního pole (jak už se to řešilo v moc vláknech) se dělá pomocí (primitivní) grafiky, ale to už je jenom detail proti herní logice.

Nahlásit jako SPAM
IP: 85.207.166.–
RePRO0
Super člen
8. 7. 2010   #5
-
0
-

Mockrát Ti děkuju Libore. Tentokrát už spojení drží a jede to tak, jak má. Ještě jednou dík.
Tento Topic nechávám stále otevřen v případě dalších komplikací (které jistě budou).

Nahlásit jako SPAM
IP: 83.240.104.–
Software: C; C++; C#; Pascal; Delphi; Java Webdesign: PHP; MySQL; CSS; jQuery; Ajax; Javascript; OOP
RePRO0
Super člen
8. 7. 2010   #6
-
0
-

Dál by mě zajímalo, jak bych mohl vyřešit to odpojení? Klient.close() mi to nechce nějak přelousknout. :-))

Ano ale jinak by to mělo být naopak, prvně TRY, potom IF, díky.

Nahlásit jako SPAM
IP: 83.240.104.–
Software: C; C++; C#; Pascal; Delphi; Java Webdesign: PHP; MySQL; CSS; jQuery; Ajax; Javascript; OOP
liborb
~ Redaktor
+18
Guru
9. 7. 2010   #7
-
0
-

Odpojení můžeš dát třebas do reakce na událost uzavírání formuláře (FormClosing).

Nahlásit jako SPAM
IP: 85.207.166.–
RePRO0
Super člen
10. 7. 2010   #8
-
0
-

Po delší době sem zase něco napíšu ohledně mého vývoje. :-)

Mám tak nějak hotový SERVER a snad i toho KLIENTA. Server naslouchá na portu 2000. Klient se tedy k tomuto serveru připojí pomocí adresy 127.0.0.1 a portu 2000, na kterým server naslouchá (samozřejmě na mém počítači to testuju, proto je zvolena localhost adresa).

Mám celkem dva problémy:

1] První problém je ten, že pokud připojím Klienta k Serveru a odešlu serveru zprávu, tak jí poté server nezobrazí a nevypíše jí do Labelu. Bude to nějaká prkotina, ale zatím jsem na ní nepřišel - chce to doladit.

-----

2] No a ten druhý problém je ten, že se u serveru nikdy nedostanu za kód:

klient = server.AcceptTcpClient();


Respektive se mi ještě nikdy nestalo, aby mi to vypsalo toto:
labelStav.Text = " Připojeno! Lokální adresa je: " + server.LocalEndpoint;


Zdrojové kódy:
> klient: http://pastebin.com/DYC1SDmT
> server: http://pastebin.com/DrajBPAK

Opět moc díky za veškeré kloubné nápady a vyřešení. :-)

Nahlásit jako SPAM
IP: 83.240.104.–
Software: C; C++; C#; Pascal; Delphi; Java Webdesign: PHP; MySQL; CSS; jQuery; Ajax; Javascript; OOP
liborb
~ Redaktor
+18
Guru
12. 7. 2010   #9
-
0
-
Nahlásit jako SPAM
IP: 85.207.166.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 48 hostů

Podobná vlákna

Připojení sitové jednotky — založil Tomass

Sitove programovani — založil silent

Obnovení síťové cesty — založil Romek

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý