Toon posts:

[C#] Overvloed aan connecties met TCPListener

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleem met het opzetten van een netwerkverbinding tussen 2 computers. (een server en client) Ik heb een applicatie die communiceert met een andere applicatie die ik allebei heb geschreven. Om dit voor elkaar te krijgen heb ik me verdiept in dit onderwerp op sites als : www.c-sharpcorner.com.
De verbinding die komt goed tot stand. De berichten die ik stuur komen ook aan. Maar na een tijd draaien worden de berichten niet meer ontvangen/verzonden. Als ik vervolgens met het commando netstat in het dos-console kijk heb ik meer dan 2 schermen vol aan connecties staan. Ik heb al geprobeerd om de code zo aan te passen dat er maar 1 connectie wordt aan gemaakt. Om dit voor elkaar te krijgen heb ik geprobeer om bij het zenden maar 1x te connecten naar een Endpoint. Tevens heb ik geprobeerd om de TcpClient globaal te declareren.
Heeft iemand een idee wat er mis gaat in mijn code: (zowel server als client gebruiken deze code)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Send(String _sendMessage, IPAddress theIPAddress)
{
    try
    {
        TcpClient _tcpClient = new TcpClient();
        _tcpClient.Connect( theIPAddress ,listenPort1);

        Stream _stream1 = _tcpClient.GetStream();

        ASCIIEncoding _asen = new ASCIIEncoding();
        byte[] _bytes = _asen.GetBytes( _sendMessage );

        _stream1.Write(_bytes, 0, _bytes.Length);
        _tcpClient.Close();
    }
    catch{}
}


Dit stuk code draait in een apparte thread die deze functie laat herhalen. (myList is globaal gedeclareerd van het type TcpListener)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void Receive()
{
    myList = new TcpListener(theLocalIPAddress ,receivePort1);
    myList.Start();

    Socket _socket1 = myList.AcceptSocket();
                
    byte[] _bytes = new byte[1024];
    int _rc = _socket1.Receive( _bytes );

    string _temp = "";
    for (int i = 0; i < _rc; i++ )
    {               
        _temp += Convert.ToChar( _bytes[i] );
    }
    
    SplitMessage( _temp );

    _socket1.Close();
    myList.Stop();
}

  • whoami
  • Registratie: December 2000
  • Laatst online: 06-05 15:36
Begin eerst eens met dit weg te halen:
code:
1
catch{}

Dit is gewoon je reinste 'struisvogel-politiek'. Als er iets fout gaat, doe je alsof er niks aan de hand is, vervang dat door:
code:
1
2
3
4
catch( Exception ex )
{
    throw;
}

Wat je ook best doet, is je Close van je TcpClient in een finally clause te steken; zo ben je er zeker van dat ie altijd gesloten wordt, ook als er een exception optreedt.

https://fgheysels.github.io/


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 05-05 22:23
Standaard worden sockets nog een tijd opengehouden om eventueel data te kunnen ontvangen die nog onderweg was. Dit kun je in plain winsock beinvloeden door socket timeouts in te stellen, weet ff niet hoe je dit in .Net fabriekt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

farlane schreef op dinsdag 14 juni 2005 @ 11:47:
Standaard worden sockets nog een tijd opengehouden om eventueel data te kunnen ontvangen die nog onderweg was. Dit kun je in plain winsock beinvloeden door socket timeouts in te stellen, weet ff niet hoe je dit in .Net fabriekt.
Ook als je close aanroept :?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik weet niet precies wat je wilt doen. Maar als je tussen 2 programma's een communicatie kanaal op wilt zetten is het mischien handiger om tijdens de loop van je programma je Connectie gewoon open te houden. Dan hoef je niet telkens een nieuwe verbinding op te zetten, dit is namelijk vrij duur om te doen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 05-05 22:23
Verwijderd schreef op dinsdag 14 juni 2005 @ 11:57:
[...]

Ook als je close aanroept :?
Ja.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-05 14:03

curry684

left part of the evil twins

whoami schreef op dinsdag 14 juni 2005 @ 11:44:
Begin eerst eens met dit weg te halen:
code:
1
catch{}

Dit is gewoon je reinste 'struisvogel-politiek'. Als er iets fout gaat, doe je alsof er niks aan de hand is, vervang dat door:
code:
1
2
3
4
catch( Exception ex )
{
    throw;
}
Wtf is het punt van een catch-all die alles blind doorgooit 8)7

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 06-05 15:36
Ja, ok, je kunt die catch even goed weglaten, maar het is in ieder geval beter dan catch{}

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ok maar wat is nou de oorzaak van de velen connecties? Dat met die Try, catch en Finally dat vat ik wel.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
curry684 schreef op dinsdag 14 juni 2005 @ 13:14:
[...]

Wtf is het punt van een catch-all die alles blind doorgooit 8)7
Codetechnisch misschien niks. Je kan er wel mee duidelijk maken dat je weet dat er fouten kunnen optreden, maar bewust hebt gekozen om de foutafhandeling niet hier te doen.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Verwijderd schreef op dinsdag 14 juni 2005 @ 17:20:
Ok maar wat is nou de oorzaak van de velen connecties? Dat met die Try, catch en Finally dat vat ik wel.
Als wat Farlane zegt klopt (dat weet ik niet zeker), dan zou je de applicatie wat langer door kunnen laten lopen en dan kijken of de verbindingen vanzelf sluiten.

  • The Fox NL
  • Registratie: Oktober 2004
  • Laatst online: 23:46
Zoals rwb al zegt zou ik de connectie langer openhouden en niet steeds connect / disconnect doen. Als je dan tien berichten doorstuurt naar een bepaald adres krijg je niet tien maar 1 open connectie.

Ik moet zeggen dat ik C# niet ken en meer ervaring heb met Java, dus pin me niet vast op wat er nu allemaal komt. Maar je hebt het over een netwerkverbinding met 2 computers (een server en client). Is het dan niet slimmer om op de server een TCPListener op te zetten die luistert naar nieuwe connecties, en de client met die TcpClient naar de server te laten connecten? Zodra je een client laat connecten naar de server, start je bij de server een nieuwe thread voor die connectie. Nadat de connectie is opgezet gebruik je die connectie om je berichtjes heen en weer te zenden. Heb je de connectie niet meer nodig, dan verbreek je hem weer.

Zoals je code er nu uitziet is er niet echt sprake van een client / server applicatie. Als ik naar je receive methode kijkt zie ik dat er daar een TcpListener wordt gestart die luistert naar binnen komende connecties. Wordt er verbinding gemaakt, dan wordt het bericht ontvangen, en daarna wordt de TcpListener en de verbinding weer gesloten. Die TcpListener zou ik enkel in de server applicatie zetten.

Dus:
Bij de server applicatie in een thread de tcplistener laten draaien. Zodra bij naar de server een verbinding wordt gemaakt (als myList.AcceptSocket() een Socket teruggeeft) start je een nieuwe thread waar je die Socket aan meegeeft, die aparte thread laat je dan luisteren naar berichten en berichten verzenden. In java heb je Socket.getInputStream en Socket.getOutputStream die streams teruggeven voor resp. het ontvangen en verzenden van berichten, ik neem aan dat Socket ook wel zoiets heeft in C#.

De client applicatie laat je connecten met de server dmv. TcpClient. Als je met je client berichten wilt versturen en ontvangen kan dat ook weer met die Streams (zie eerder gegeven url). Als je de client afsluit zorg je ook weer dat de verbinding met de server verbroken wordt (_tcpClient.close() bijvoorbeeld)

Zie hier een voorbeeldje van een server en een client in C# (eerste hit in google bij zoeken naar C# Socket)

Veel plezier verder

Verwijderd

Topicstarter
Ok bedankt! _/-\o_ Ik ga het ff bekijken.

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 05-05 14:48
Orphix schreef op dinsdag 14 juni 2005 @ 17:47:
[...]

Als wat Farlane zegt klopt (dat weet ik niet zeker), dan zou je de applicatie wat langer door kunnen laten lopen en dan kijken of de verbindingen vanzelf sluiten.
Het is normaal dat verbindingen na het sluiten door de applicatie nog zichtbaar blijven met netstat in de TIME_WAIT state. In Windows is dit standaard 4 minuten maar dit kan je aanpassen in de registry in HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters, TcpTimedWaitDelay. Met Google kan je veel meer hierover vinden als je zoekt op TIME_WAIT, TcpTimedWaitDelay, lingering, etc.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 05-05 22:23
In winsock kun je dit beinvloeden met de SetSockOpt( ....., SO_LINGER, ... )opties.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1