www.mikrocontroller.net

Forum: PC-Programmierung Connection reset by peer


Autor: Carolin Zapa (seobalis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich versuche eine TCP Verbindung zwischen server und client zu bauen. 
Der Client soll so schnell wie möglich senden.

Die Verbindung brecht ab wenn ich in der client-Seite keine 
sleep(1)-funktion benutze, und ich bekomme die Meldung "Connection reset 
by peer". Wie kann ich diese Fehler korrigieren ohne sleep zu benutzen.?
Ich bedanke mich schon mal für euere Hilfe.

Grüße,
Carolin
// client code
i=0;
while(1){
  send_len = send(sock, (char*)&i, sizeof(unsigned int), 0);
  i++;
  if(send_len < 0){
    //printf("connection error\n");
    close(sock);
    exit(1);
  }
  //sleep(1);
}



//server code
while(1){
  recv_len = recv(connect_sock, (char*)&sequence, 10, 0);
  if(recv_len > 0){
    printf("recv a number = %d \n, sequence);
  }
  else{
    perror("recv():");
    close(connect_sock);
    close(sock);
    exit(1);
  }
}

Autor: zwieblum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da fehlt was - der rest des codes.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zwieblum hat Recht.

Mit dem restlichen Code wird es aber auch nicht gehen, weil recv()
meines wissens nicht wartet, bis eine Nachricht zum Lesen da ist.
D.h. wenn der Sender auch nur einmal nicht nachkommt, liefert recv()
gleich 0 und der Server macht ein close(); für den Client ist das
dann der "reset by peer".

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tja, da würde der rest des codes aufschluss geben, ob der socket 
blocking ist oder nicht ...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob blocking oder nicht, eine zumindest rudimentäre Auswertung des 
Returncodes würde schon helfen
while(1){
  recv_len = recv(connect_sock, (char*)&sequence, 10, 0);
  if(recv_len > 0){
    printf("recv a number = %d \n, sequence);
  }
  else if( recv_len == 0 ) {    // sender has shut down
    perror("recv():");
    close(connect_sock);
    close(sock);
    exit(1);
  }
  else {
    switch( errno ) {
      case EBADF:
        perror( "s is an invalid descriptor.\n" );
        break;

      case ECONNABORTED:
        perror( "The virtual circuit was aborted because of a timeout or other failure.\n" );
        break;

      case ECONNRESET:
        perror( "The virtual circuit was reset by the remote host executing a hard or abortive close.\n" );
        break;
      case EFAULT:
        perror( "buf is an invalid pointer.\n" );
        break;

      case EINTR:
        perror( "A signal interrupted the recv() call.\n" );
        break;

      case EINVAL:
        perror( "The socket was not bound using bind(), or an invalid flag was specified, or len was 0 or negative.\n" );

      case EMSGSIZE:
        perror( "The message was too large to fit the specified buffer.\n" );

      case ENETDOWN:
        perror( "The network subsystem has failed.\n" );
        break;

      case ENETRESET:
        perror( "The connection is broken; the remote host reset.\n" );
        break;

      case ENOTCONN:
        perror( "The socket is not connected.\n" );
        break;

      case ENOTSOCK:
        perror( "s is not a socket descriptor.\n" );
        break;

      case EOPNOTSUPP:
        perror( "MSG_OOB was specified on socket that does not support out of band data.\n" );
        break;

      case ESHUTDOWN:
        perror( "The socket has been shut down.\n" );
        break;

      case ETIMEDOUT:
        perror( "The connection has been dropped because of a network failure.\n" );
        break;

      case EWOULDBLOCK:
        break;  // receive would block, not very interesting
    }
  }
}

Selbiges senderseitig.

Gerade bei Netzwerksachen ist das Auswerten der Return und Fehlercodes 
eines der Dinge, die Licht ins Dunkel bringen können und auf die man nie 
verzichten sollte. Manchmal muss man auch die Fehlercodes senderseitig 
und empfängerseitig in der zeitlich richtigen Reihenfolge sehen, um 
rauszukriegen was da warum falsch gelaufen ist.
Auf dieses Feature zu verzichten, bedeutet das Stochern im Nebel dem 
Arbeiten bei gutem Licht vorzuziehen.

Autor: Stephan M. (stephanm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, dass Du "connection reset by peer" als Fehler bekommst ist seltsam. 
Das riecht nach Firewall oder dergleichen. Um so wichtiger ist es 
tatsächlich mal alle Netzwerk-I/O-relevanten Aufrufe wie von Karl heinz 
Buchegger vorgeschlagen mit einer vollständigen und korrekten 
Fehlerbehandlung zu verbrähmen, so dass man die Fehlerursache ggf. nach 
dem Ausschlussverfahren finden kann.

(Allerdings verstehe ich Karl heinz's switch()-Konstrukt nicht... IMHO 
reicht doch perror("read") oder dergleichen.)

Funktioniert Dein Code denn, wenn Client und Server lokal auf ein und 
demselben Rechner laufen und auf diesem Rechner sämtliche 
möglicherweise störenden Komponenten wie Firewall (auch die von einer 
möglichen Antivirus-Software) und andere Netzwerksauereien (ich denke da 
an all das was neben klassischem Firewalling sonst noch mit iptables 
machbar ist) abgeschalten sind?

Eine andere Möglichkeit, die mir noch einfällt, ist die falsche 
Verwendung von close(2) oder die irrtümliche Verwendung von close(2) 
statt shutdown(2). Allerdings bin ich mir da nicht sicher, ob man dann 
"connection reset by peer" als Fehler beim Senden/Empfangen bekommen 
würde (eigentlich hätte ich auf einen anderen Fehler getippt).

> Der Client soll so schnell wie möglich senden.

Es gibt eine Reihe von Dingen die dazu beachtet werden sollten. Los 
gehts mit diversen Socket-Options (TCP_CORK, TCP_NODELAY, SO_xxxBUF 
fallen mir spontan ein), weiter über Blocking I/O vs. Async IO, 
select(2) vs. epoll(2) vs. sonstwas(X) bis hin zu Einstellungen, die 
global für das gesamte System vorzunehmen sind (Stichwort sysctl).

Stephan

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

> Mit dem restlichen Code wird es aber auch nicht gehen, weil recv()
> meines wissens nicht wartet, bis eine Nachricht zum Lesen da ist.

Doch. Es sei denn der Socket wurde explizit auf nonblocking umgestellt.

Autor: Carolin Zapa (seobalis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bedanke mich für euere Antworte. Ich habe den Fehlercode ausgewertet 
wie Karl heinz Buchegger geschrieben hat, und ich bekomme in 
Empfänge-Seite diese Meldung nach ein mal empfangen:

s is not a socket descriptor.
: Socket operation on non-socket

Falls diese Information helfen kann:

Socket ist auf blocking mode
Sender und Empfänger laufen auf demselben Rechner

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Carolin Zapa schrieb:

> s is not a socket descriptor.
> : Socket operation on non-socket

Und das ist dir nicht deutlich genug? Was auch immer das ist, was du dem 
Aufruf übergibst, es ist kein korrekt und erfolgreich geöffneter Socket. 
Also liegt das Problem möglicherweise davor, wo der Socket herkommt, 
oder er wurde zwischenzeitlich wieder geschlossen.

Autor: Carolin Zapa (seobalis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Carolin Zapa schrieb:
>
>> s is not a socket descriptor.
>> : Socket operation on non-socket
>
> Und das ist dir nicht deutlich genug? Was auch immer das ist, was du dem
> Aufruf übergibst, es ist kein korrekt und erfolgreich geöffneter Socket.
> Also liegt das Problem möglicherweise davor, wo der Socket herkommt,
> oder er wurde zwischenzeitlich wieder geschlossen.

Ja. Das ist mir auch klar dass der Socket geschlossen wurde. Aber Es ist 
mir noch nicht klar wieso der geschlossen wurde und wo wird es gemacht? 
Wieso kommt das Problem nicht wenn ich in Sender-Seite ein 
Sleep-Funktion rufe.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Carolin Zapa schrieb:

> Ja. Das ist mir auch klar dass der Socket geschlossen wurde. Aber Es ist
> mir noch nicht klar wieso der geschlossen wurde und wo wird es gemacht?

Dann wirf in deinen (zum größten Teil hier unbekannten) Code noch ein 
paar zusätzliche printf rein, die dir sagen, was in welcher Reihenfolge 
gemacht wird.
Debuggen ist zwar eine Kunst für sich, aber zumindest die Idee überall 
printf reinzugeben, damit einem das Programm mitteilt was es gerade 
macht, sollte eigentlich ziemlich naheliegend sein.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.