|
» myCSharp.de Diskussionsforum |
|
|
|
Autor
 |
|
ikaros
myCSharp.de-Mitglied
Dabei seit: 27.05.2005
Beiträge: 1.739
|
|
FIN ist ein Signal -> Bedeutung = Bye. Heisst: Vedrbindung angenommen, irgendwas getan(oder nicht) und Verbindung beendet(Socket.Close als Entsprechung). In demFall wird ein FIN gesendet(Benutze Etheral oder einen anderen Packetviewer um es zu sehen). Blöd ist nur das der .Net Client das nicht meldet(zumindest nicht direkt).
Lösung ist das pollen des Readers auf nicht in der MSDN-beschriebenen Weise. Hatte dieses Problem erst vor 3 - 4 Monaten gelöst, muss erst nachschauen.
Es ist feststellbar im Read, weiss nur gerad nicht wie(nachschauen halt, Auswendig hab ich es gerade nicht).
|
|
03.07.2007 00:16
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
idontwantaname
myCSharp.de-Mitglied
Dabei seit: 18.06.2006
Beiträge: 86
Entwicklungsumgebung: Visual C# 2008 Express Edition Herkunft: Österreich
Themenstarter
|
|
Könntest du das vielleicht nachsehen wie das geht?
Weil das wäre echt wichtig für mich!
Vielen Dank jetzt schon mal für deine bisherige und noch zukünftige Mühe
Lg oli
|
|
03.07.2007 12:38
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Hallo idontwantaname,
ich bin vor Ewigkeiten zu dem Entschluss gekommen, dass es keine zuverlässige Methode gibt, einen TCP/IP Abbruch mitzubekommen. Einzig was hilft ist, dass bei einem "Read" oder bei einem "Write" ein Try-Catch darum zu bauen und im Fehlerfall einen erneuten Verbindungsaufbau zu probieren.
Es gibt auch praktische keine Möglichkeit festzustellen, wenn auf der Gegenseite einfach so jemand das Kabel abzieht. Es gibt hier keine Möglichkeit zu intervenieren oder informiert zu werden. Schon allein deshalb ist Try-Catch eine vernünftige Lösung.
Zusatzinfo:
Ich habe damals auch schon festgestellt, dass MS-Windows2000 zusammen mit Win2003 Server eine "kranke" TCP/IP Verbindung aufbaut, bei der nicht alle gewollten Verbindungsabbrüche gesenset wurden (Known MS-Bug).
Grüße
Norman-Timo
|
|
04.07.2007 13:57
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
ikaros
myCSharp.de-Mitglied
Dabei seit: 27.05.2005
Beiträge: 1.739
|
|
Zitat: |
Original von Borg
Einen eigenen TimeOut implementieren. |
Ja genau, wenn man weiss wie...
Den Timeout muss man bemerken. Zu meiner Schande - ich hab die Lösung nur immer noch nicht parat.
(Ist aber eigentlich simpel, ...)
_ mea culpa, vertröste auf später...
(trennen ist das derzeitige problem)
Edit: (Stick vergessen)
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ikaros am 05.07.2007 01:04.
|
|
05.07.2007 00:53
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
idontwantaname
myCSharp.de-Mitglied
Dabei seit: 18.06.2006
Beiträge: 86
Entwicklungsumgebung: Visual C# 2008 Express Edition Herkunft: Österreich
Themenstarter
|
|
Also ich habe das Problem jetzt selbst gelöst.
Hier die wichtigen Teile:
C#-Code: |
try
{
SocketError error;
int size = client.Receive(buffer, 0, bufferSize, SocketFlags.None, out error);
if (error == SocketError.Success && size > 0)
{ }
else
{
}
}
catch
{
}
|
Hier ist meine Lösung gekapselt in einer Klasse mit Threading und allem drumherum:
C#-Code: |
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SocketTest
{
public class TcpServer
{
public delegate void ClientConnected(Socket client);
public event ClientConnected OnClientConnected;
public delegate void DataReceived(Socket client, byte[] data);
public event DataReceived OnDataReceived;
public delegate void ClientDisconnected(Socket client);
public event ClientDisconnected OnClientDisconnected;
private Socket socket;
private int port;
private int bufferSize;
private Thread listeningThread;
private List<Thread> clientThreads;
private bool active;
public bool Active
{
get
{
return active;
}
}
public TcpServer(int port, int bufferSize)
{
this.port = port;
this.bufferSize = bufferSize;
clientThreads = new List<Thread>();
}
public void Start(int backlog)
{
active = true;
try
{
IPEndPoint endpoint = new IPEndPoint(new IPAddress(0), port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(endpoint);
socket.Listen(backlog);
listeningThread = new Thread(new ThreadStart(listen));
listeningThread.Start();
}
catch
{
active = false;
}
}
public void Stop()
{
try
{
active = false;
socket.Close();
}
catch { }
}
private void listen()
{
while (active)
{
try
{
Socket client = socket.Accept();
if (OnClientConnected != null)
OnClientConnected(client);
Thread thread = new Thread(new ParameterizedThreadStart(work));
clientThreads.Add(thread);
thread.Start(client);
}
catch
{
Stop();
}
}
}
private void work(object parameter)
{
Socket client = (Socket)parameter;
byte[] buffer = new byte[bufferSize];
SocketError error = SocketError.Success;
while (active && client.Connected)
{
try
{
int size = client.Receive(buffer, 0, bufferSize, SocketFlags.None, out error);
if (error == SocketError.Success && size > 0)
{
byte[] data = new byte[size];
Array.Copy(buffer, data, size);
if (OnDataReceived != null)
OnDataReceived(client, data);
}
else
{
if (OnClientDisconnected != null)
OnClientDisconnected(client);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
catch
{
if (OnClientDisconnected != null)
OnClientDisconnected(client);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
}
}
}
|
|
|
06.07.2007 00:00
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Hallo idontwantaname,
habe den Code nur eben überflogen, und sage, dass das für Deine aktuellen Zwecke wohl ausreicht (sofern Du getestet hast, ob's auch das tut, was es auf den ersten Blick soll :-).
Gruß
Norman-Timo
|
|
06.07.2007 14:10
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Hallo idontwantaname,
nein, nein, so ernst ist das nicht ;-)
Ich hätte in meiner Lösung wahrscheinlich noch so etwas wie 3x Reconnect Versuch eingebaut, und auch versucht um das Read den oben genannten Timer einzubauen, denn ein TCP/IP Timeout ist standardmäßig auf 1,5 Minuten eingestellt (WinXP).
Aber das sind alles Ergänzungen, keine Verbesserungsvorschläge und für Deinen Anwendungszweck zunächst Oversize. Ich würde Dir empfehlen Dir dann darüber Gedanken zu machen, wenn es soweit ist. Deine Lösung eignet sich gut für solche Anforderungswechsel, und ist meiner Meinung nach deshalb wirklich gut.
Wie gesagt, habe Deinen Code nur überflogen, nicht analysiert und auch nicht ausprobiert ;-)
Gruß
Norman-Timo
|
|
06.07.2007 22:14
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
ikaros
myCSharp.de-Mitglied
Dabei seit: 27.05.2005
Beiträge: 1.739
|
|
Es ist ja auch unwichtig, wenn dein Problem damit gelöst ist. Ich unterstellte wohl einfach ein anderes Problem(das ich so Aufgrund der Beschreibung anfangs so annahm) - Dem scheint nicht so.
Ich seh das so: ist dein Problem gelöst, ist alles ok.
Zweifel bei mir kam nur bei Problemen die ich lösen durfte, und ähnlich erschienen(Anfangsbeschreibung)...
|
|
09.07.2007 01:29
|
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
dutchnomad
myCSharp.de-Mitglied
Dabei seit: 23.07.2007
Beiträge: 1
Entwicklungsumgebung: Visual Studio 2005 Herkunft: Niederlande
|
|
Hallo, Ich habe die genannte code implementiert und getestet. Es scheint zu functionieren, aber wass Ich sehe ist das Folgende:
Mehrere client habe ein Connection mit den Server gemacht, und data is angekommen.
Wann Ich mit netstat /a untersuchte was mit nicht mehr benutzte connection passiert ware sah Ich das sie nicht 'deleted' werden. Wissen Sie wie Ich das Problem kann losen.
Grusse,
Jan, Niederlande
|
|
26.07.2007 12:29
|
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
|