2013-02-12 5 views
5

Ich fange gerade an, Netzwerkprogrammierung in C zu lernen. Ich habe einige Tests gemacht, aber ich blieb mit einem Fehler stecken.C - "Transport Endpunkt ist nicht verbunden" nach dem ersten recv() Anruf

Ich habe einen Klienten:

client.c

#include <string.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <errno.h> 

int main(void) 
{ 
    struct addrinfo hints, *res; 
    int sock; 

    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 

    getaddrinfo("localhost", "5996", &hints, &res); 
    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
    connect(sock, res->ai_addr, res->ai_addrlen); 
    char data[64]; 
    int len = 13; 
    int br = recv(sock, data, len, 0); 
    printf("%s\n%s\n%d\n", strerror(errno), data, br); 
    return 0; 
} 

und einen Server:

server.c

#include <string.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

#define MYPORT "5996" 
#define BACKLOG 10 

int main(void) 
{ 
    struct sockaddr_storage their_addr; 
    socklen_t addr_size; 
    struct addrinfo hints, *res; 
    int sockfd, new_fd; 

    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = AI_PASSIVE; 

    getaddrinfo(NULL, MYPORT, &hints, &res); 

    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
    bind(sockfd, res->ai_addr, res->ai_addrlen); 
    listen(sockfd, BACKLOG); 

    addr_size = sizeof their_addr; 
    new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size); 
    char *msg = "Hello World!!"; 
    int len = strlen(msg); 
    int bs = send(new_fd, msg, len, 0); 
    close(sockfd); 
} 

Wenn ich den Server starten , es wartet für eine Verbindung, und wenn ich den Client starte ich bekomme die Nachricht "Hallo Welt !!", aber dann, für eine Minute oder so, wenn ich versuche, den Server zu starten und dann den Client erneut ausführen, bekomme ich die Nachricht " Transportendpunkt ist nicht verbunden " vom strerror() Aufruf.

Ich habe andere Fragen dazu gelesen, aber das Problem war, dass die Daten an den Socket gesendet werden sollten, die von der accept() Aufruf zurückgegeben ... aber ich denke, das ist, was ich tue. Was mache ich falsch ?? ... Ich weiß, es ist etwas Dummes, aber ich bin ein echter Anfänger.

+1

Sie sollten den Rückgabewert von 'connect()' überprüfen und 'errno' betrachten, falls die Verbindung fehlgeschlagen ist. –

+0

Vielen Dank für den letzten Absatz in Ihrem Beitrag! :) Ich habe total vermisst, dass ich das in meinem Code falsch gemacht habe! –

Antwort

5

Wenn Sie Ihren Server jedes Mal am selben Port neu starten, stellen Sie möglicherweise fest, dass der Port weiterhin vom Betriebssystem verwendet wird. Dies ermöglicht Zeit für die Zustellung von laufenden Anforderungen für Clients vom letzten Serverlauf.

Sie können over-ride dies durch setsockopt für Opcode Aufruf SO_REUSEADDR

sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
int reuse = 1; 
int err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); 
if (0 == err) 
    err = bind(sockfd, res->ai_addr, res->ai_addrlen); 

Beachten Sie, dass die oben genannten Schnipsel prüft Fehler zurückgibt. Sie hätten das Problem (wenn nicht die Lösung) selbst entdeckt, wenn Sie den Rückgabecode jedes Anrufs überprüft hätten.

+0

etwas wie 'setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, & ja, sizeof (int));'? ..und wo soll ich es hinstellen? – Sylar

+0

Ja. Nachdem Sie Ihren Socket erstellt haben, aber bevor Sie 'bind' aufrufen. Ich werde den Code in meiner Antwort aktualisieren, um dies klarer zu machen. – simonc

+0

Vielen Dank !! Es klappt! ..Ich war wie für eine Stunde stecken !! – Sylar

Verwandte Themen