2016-07-08 5 views
2

Ich versuche, in die Netzwerkprogrammierung zu bekommen und habe eine Anleitung für Sockets folgen. Ich habe einen einfachen Windows TCP-Server und einen Client in C geschrieben, aber ich kann nicht scheinen, dass sie funktionieren. Wenn der Client eine Verbindung herstellt, löst der Server den Fehler 'Fehlerhafte Dateibeschreibung' aus und wird geschlossen. Ich verstehe nicht, wie der Datei-Deskriptor, der gerade von accept() erstellt wurde, schlecht sein kann. Ich habe darüber recherchiert und nur Leute gefunden, die die Datei vor dem Lesen geschlossen hatten, was ich nicht getan habe. Hier'Bad file descriptor' Fehler auf einem akzeptierten Socket

ist der Code:

SERVER

#include <stdio.h> 
#include <stdlib.h> 
#include <winsock2.h> 

int main(int argc, char *argv[]) 
{ 
    WSADATA WSAData; 
    WSAStartup(MAKEWORD(2,0), &WSAData); 

    SOCKET sock, newsock; 
    int portno, clilen; 
    char buffer[256]; 
    SOCKADDR_IN serv_addr, cli_addr; 
    int n; 

    sock = socket(AF_INET, SOCK_STREAM, 0); 

    if (sock < 0) 
    { 
     perror("Error opening socket"); 
     exit(1); 
    } 

    memset((char *) &serv_addr, 0, sizeof(serv_addr)); 
    portno = 5001; 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 

    if (bind(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0) 
    { 
     perror("Eror on binding"); 
     exit(1); 
    } 

    listen(sock, 5); 
    clilen = sizeof(cli_addr); 

    newsock = accept(sock, (SOCKADDR *) &cli_addr, &clilen); 
    if (newsock < 0) 
    { 
     perror("Error on accept"); 
     exit(1); 
    } 

    memset(buffer, 0, 256); 
    n = read(newsock, buffer, 255); 

    if (n < 0) 
    { 
     perror("Error reading from socket"); 
     exit(1); 
    } 

    printf("Here is the message : %s\n", buffer); 

    n = write(newsock, "I got your message", 18); 
    if (n < 0) 
    { 
     perror("Error writing to socket"); 
     exit(1); 
    } 

    WSACleanup(); 
    return 0; 
} 

CLIENT

#include <stdio.h> 
#include <stdlib.h> 
#include <winsock2.h> 

int main(int argc, char *argv[]) 
{ 
    WSADATA WSAData; 
    WSAStartup(MAKEWORD(2,0), &WSAData); 

    SOCKET sock; 
    int portno, n; 
    SOCKADDR_IN serv_addr; 
    HOSTENT *server; 
    char buffer[256]; 

    if (argc < 3) 
    { 
     fprintf(stderr, "Usage : %s hostname port\n", argv[0]); 
     exit(0); 
    } 

    portno = atoi(argv[2]); 
    sock = socket(AF_INET, SOCK_STREAM, 0); 
    if (sock < 0) 
    { 
     perror("Error opening socket\n"); 
     exit(1); 
    } 

    server = gethostbyname(argv[1]); 

    if (server == NULL) 
    { 
     perror("Error, no such host"); 
     exit(1); 
    } 

    memset((char *) &serv_addr, 0, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length); 
    serv_addr.sin_port = htons(portno); 

    if (connect(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0) 
    { 
     perror("Error connecting to server"); 
     exit(1); 
    } 

    printf("Please enter your message : "); 
    memset(buffer, 0, 256); 
    fgets(buffer, 255, stdin); 

    n = write(sock, buffer, strlen(buffer)); 
    if (n < 0) 
    { 
     perror("Error writing to socket"); 
     exit(1); 
    } 

    memset(buffer, 0, 256); 
    n = read(sock, buffer, 255); 

    if (n < 0) 
    { 
     perror("Error reading from socket"); 
     exit(1); 
    } 

    printf("%s\n", buffer); 

    WSACleanup(); 
    return 0; 
} 

... Und hier ist die Ausgabe für alle Fälle:

C:\...myfolder>server 
*here it does nothing until I start the client with "client 127.0.0.1 5001" in another window* 
Error reading from socket: Bad file descriptor 

Siehst du, Was ist los mit meinem Kabeljau? e? Vielen Dank im Voraus für Ihre Hilfe!

Antwort

3

Ich würde dies in einen Kommentar setzen, aber versuchen Sie mit der recv() Funktion statt lesen(). Dies liegt daran, dass read() nicht in die Socket-API aufruft, so dass der Dateideskriptor für Windows nicht gültig ist.

Gleichzeitig sollten Sie in Ihrem Client send() anstelle von write() verwenden.

+0

Danke, es funktioniert jetzt! Bedeutet dies, dass die Windows-Socket-API nicht auf die gleiche Weise wie die Linux-Sockets implementiert ist? Wie in, sind meine Socket-Variablen wirklich Dateideskriptoren oder nur eine Kennung speziell für Winsock gemacht? – Toctave

+0

Ist * irgendetwas * wirklich ein Dateideskriptor unter Windows, oder ist das alles nur ein Haufen Kludges, die vorgeben, ein Dateideskriptor zu sein? –

+0

Sie haben einen Punkt. Aber sind dann alle diese Kludges die gleiche Art von Kludis? Sind "Socke" und "Stdin" die gleiche Art von Dingen, und wenn nicht wie unterscheiden sie sich? – Toctave

Verwandte Themen