Hallo,
ich versuche mich an einem TCP-Server in C#, der Daten von einem
TCP-Client in C empfängt. Das Problem ist, dass der Server nach einer
willkürlichen Anzahl von Empfangvorgängen nichts mehr empfängt, der
Client jedoch weiterarbeitet.
1
mythread=newThread(newThreadStart(listen_tcp));
2
mythread.start();
3
4
privatevoidlisten_tcp()
5
{
6
stringtmp=null;
7
IPAddressipAddress=IPAddress.Any;
8
listener=newTcpListener(ipAddress,12345);
9
listener.Start();
10
Console.WriteLine("Server is running");
11
Console.WriteLine("Listening on port "+12345);
12
Console.WriteLine("Waiting for connections...");
13
s=listener.AcceptSocket();
14
Console.WriteLine("Connection accepted from "+s.RemoteEndPoint);
15
while(s.Connected==true)
16
{
17
18
byte[]b=newbyte[100];
19
char[]c=newchar[100];
20
intk=s.Receive(b);
21
//Console.WriteLine("Received:");
22
for(inti=0;i<k;i++)
23
{
24
Console.Write(Convert.ToChar(b[i]));
25
c[i]=Convert.ToChar(b[i]);
26
}
27
tmp=newstring(c);
28
convert_vs(tmp);
29
tmp=null;
30
ASCIIEncodingenc=newASCIIEncoding();
31
s.Send(enc.GetBytes("Server responded"));
32
//Console.WriteLine("\nSent Response");
33
if(s.Connected==false)s.Close();
34
if(shut_down==true)
35
{
36
s.Close();
37
mythread.Abort();
38
Console.WriteLine("Mythread wurde beendet");
39
}
40
41
}
42
}
Teilweise kommt die Meldung: Der Thread xx hat mit Fehlercode 0x00
geendet.
Kennt jemand das Problem bzw. hat sogar eine Lösung dafür?
Viele Grüße,
Martin
Martin schrieb:> Teilweise kommt die Meldung: Der Thread xx hat mit Fehlercode 0x00> geendet.
.Net wirft eigentlich aussagen kräftigere Fehlermeldungen.
Ansonsten umschließe den Bereich mal mit try-catch und lass die
Fehlermeldung entweder protokollieren oder aufpoppen.
Dein Threading arbeitet aber etwas komisch
Generell gibt es einen Thread, der den Port offen hält, und wenn dann
sich jemand auf den Port verbindet, leitet der erste Thread, das ganze
weiter und spawnt einen neuen Thread, der sich nur um diese eine
Verbindung kümmert.
Wenn das C-Programm irgendwann die Verbindung schließt, dann endet auch
dein Thread, d.h. es kann sich noch nichtmals neustarten.
Martin schrieb:> s = listener.AcceptSocket();
An der stelle musst du/solltest du einen eigenen Thread aufmachen.
Martin schrieb:> mythread.Abort();
Was soll das? Ein einfaches break reicht völlig aus.
Martin schrieb:> if (s.Connected == false) s.Close();
Das schließen sollte immer hinter dem while block passieren und nicht
nur manchmal wenn die Verbindung weshalb auch immer nicht mehr connected
ist...
Martin schrieb:> if (shut_down == true)
gehört in die while Bedingung.
Martin schrieb:> Kennt jemand das Problem bzw. hat sogar eine Lösung dafür?
Überdenke deinen Programmfluss da geht einiges durcheinander...
Nach einer Weile kommt nichts mehr beim Server an. Beende ich dann das
Client Programm und starte es neu, kann ich mich laut Client erfolgreich
verbinden, die Bestätigung im Server Programm bleibt aber aus.
du muss deinen Thread auch den socket übergeben! du machst es jetzt mit
einen Globalen variabel in der Klasse das geht aber nciht, weil du nur
eine Variabel hast aber jeder client braucht seinen eigenen socket.
Ich denke du solltest etwas einfacher anfangen, lerne erstmal die
Sprache bevor du mit Client-Server verbindungen anfängst.
Tu Dir und mir einen Gefallen und kommentiere mal jede Zeile mit dem was
du da eigentlich machst. Es ist nicht besonders einfach deinem
Gedankengang da zu folgen.
Um so früher Du damit anfängst um so besser, den am Ende machst Du das
dann doch nicht... kenne ich leider von mir all zu gut :)
Funkioniert so leider auch nicht, das übergeben des cl_socket nimmt er
so nicht hin. Ich habe schon recht viel aussen rum gebaut und würde das
jetzt ungern alles wegschmeissen, wär super wenn mir da jemand einen
konkreten Tip geben könnte.
Martin schrieb:> wär super wenn mir da jemand einen> konkreten Tip geben könnte.
Teil Das Problem auf: Eine Klasse welche einen Socket im Konstruktor
übernimmt, einen Thread startet und von dem Socket liest/schreibt.
In der Serverklasse erzeugst du bei jedem Accept einfach eine neue
Instanz der neuen Klasse.
Das ist nicht nur universeller sondern auch weniger Fehleranfällig.
Hier noch eine Variante bei der jedesmal eine neue Instanz der My_server
Klasse erstellt wird. Kommen keine Werte mehr an und ich connecte
erneut, erhalte ich allerdings gleich von Anfang an keine Werte.
Martin schrieb:> tmp = null;> ASCIIEncoding enc = new ASCIIEncoding();
Was soll das bewirken?
Martin schrieb:> my[count] = new My_server(s);> count++;AUA was soll sowas? Bitte nicht solche Konstrukte in einer Schleife
ohne Boundcheck und was soll das überhaupt?
1) C# kennt Listen welche sich um das Speichermanagment kümmern
2) du verwendest die Referenz nie also wozu aufheben?
Martin schrieb:> Kommen keine Werte mehr an und ich connecte> erneut, erhalte ich allerdings gleich von Anfang an keine Werte
Zeig doch mal deinen Clientcode.... der Server sieht (bis auf die
Anmerkungen) ganz okay aus.
Was meinst du genau mit Boundcheck?
> ASCIIEncoding enc = new ASCIIEncoding(); hat keine Funktion hier, hab ich
vergessen rauszuschmeissen. Grüße Martin