Kleines Problem in Client-/Server-Programm in C



  • Guten Morgen,

    bin bei der Suche nach einer Lösung für ein kleines Problem über Google auf dieses Forum gestossen.

    Das Programm ist sehr einfach, jedoch kann ich mit dem Client nicht auf den Server verbinden, bei newconnection() stoppt das Programm jeweils (in netclt.c implementiert).

    Hab schon alles x-mal durchgesehen, ich finde keinen Fehler. Vielleicht sieht ja jemand von euch wo das Problem liegt?! Wäre echt froh, denn ich habe schon Stunden damit verschwendet...

    Hier noch der Code von Client und Server (das Problem könnte evtl. auch am Server liegen...).

    //client.c
    #include <stdio.h>
    #include "netclt.c"
    #include "keysender.c"
    
    #define PORT 999
    
    int main(int argc, char ** argv){
      int sockfd;  // socket file descriptor
      int keystatus = 0; // contains status of keys
      // Check if enough arguments (ip-address, port)
      if(argc < 2) {
        printf("Too few arguments\n");
        printf("Usage: %s <server-ip-address>\n\n", argv[0]);
        return -1;
      }
    	char* ipaddr = argv[1];
      // request socket
      if(getsocket(&sockfd) != 0){
        printf("%s\n", " Socket request failed.");
        return -1;
      }
      else{
        printf("%s\n", " Socket request successful.");
      }
      // open connection
      if(newconnection(&sockfd, PORT, ipaddr) != 0){
        printf("%s\n", " Establishing connection failed.");
        return -1;
      }
      else{
        printf("%s\n", " Establishing connection successful.");  
      }
    
      // Connection is now established. Ready to receive data from server.
      while(1){
        if(recvkeystat(&sockfd, &keystatus) != 0){
          printf("%s\n", " Could not receive keystatus.");
          return -1;
        }
        // Keystatus now transmited. Simulate keypress.
        if(presskeys(keystatus) != 0){
          printf("%s\n", " Could not simulate keypress.");
        }
      }
      return 0;
    }
    
    //netclt.c
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <stdbool.h>
    
    /*
    Request for socket
    @ int *sockfd: pointer to socket file descriptor
    */
    int getsocket(int *sockfd){
      *sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if(*sockfd == -1){
        return -1;
      }
      return 0;
    }
    
    /*
    Open connection to server
    @ int *sockfd: pointer to socket file descriptor
    */
    int newconnection(int *sockfd, int port, char* ipaddr){
      // Adressinformation for ip-connection
      struct sockaddr_in serv_addr;
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_port = htons(port);
      serv_addr.sin_addr.s_addr = inet_addr(ipaddr);
      memset(&serv_addr.sin_zero, 0, sizeof(serv_addr.sin_zero));
      // Try to connect
      if(connect(*sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0){
        return -1;
      }
      return 0;
    }
    
    /*
    Receive keystatus
    @ int *sockfd: pointer to socket file descriptor
    @ int *keystat: pointer to int which contains keystatus
    */
    int recvkeystat(int *sockfd, int *keystat){
      int position;
      do {
        position = recv(*sockfd, keystat, sizeof(*keystat), 0);
        if(position == -1){
          return -1;
        }
      } while(position > 0);
      return 0;
    }
    
    /*
    Close socket
    @ int *sockfd: pointer to socket file descriptor
    */
    int closesocket(int *sockfd){
      return close(*sockfd);
    }
    
    //netsvr.c
    
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <stdbool.h>
    
    /*
    Request for socket and bind
    @ int *sockfd: pointer to socket file descriptor
    */
    int getsocket(int *sockfd){
      *sockfd = socket(AF_INET, SOCK_STREAM, 0);
      if(*sockfd == -1){
        return -1;
      }
      return 0;
    }
    
    /*
    Bind socket to port
    @ int *sockfd: pointer to socket file descriptor
    @ int port: portnumber
    */
    int bindport(int *sockfd, int port){
      // Adressinformation for ip-connection
      struct sockaddr_in my_addr;
      my_addr.sin_family = AF_INET;
      my_addr.sin_port = port;
      my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      // Bind to port
      if(bind(*sockfd, (struct sockaddr*) &my_addr, sizeof(my_addr)) != 0){
        return -1;
      }
      return 0;
    }
    
    /*
    Listen for connection
    @ int *sockfd: pointer to socket file descriptor
    */
    listconn(int *sockfd){
      if(listen(*sockfd, 5) != 0){ // int backloop = 5 noch aendern!!!
        return -1;
      }
      return 0;
    }
    
    /*
    Accept connection
    @ int *sockfd: pointer to socket file descriptor for listening
    @ int *keysockfd: pointer to socket file descriptor for new connection
    @ struct sockaddr_in *clientdata: Datastructure for saving details about client
    */
    int acccon(int sockfd, int *keysockfd, struct sockaddr_in *clientdata){
      socklen_t sin_size = sizeof(struct sockaddr_in);
      struct sockaddr_in tempcd = *clientdata; // optimieren: nicht umweg ueber tempcd !!! wie?
      // printf("%s", "vor accept");
      // *keysockfd = accept(sockfd, (struct sockaddr *) &clientdata, &sin_size);
        *keysockfd = accept(sockfd, (struct sockaddr *) &clientdata, &sin_size);
      printf("%s", "nach accept");
      if(*keysockfd == -1){
        printf("%s\n", "5.1");
        return -1;
      }
      printf("%s\n", "5.2");
      return 0;
    }
    
    /*
    Send keystatus to client
    @ int *keysockfd: pointer to socket file descriptor for new connection
    @ inst keystat: Keystatus
    */
    int sendkeystat(int* keysockfd, int keystat){
      int len = sizeof(int);
      if(send(*keysockfd, &keystat, len, 0) == -1){
        return -1;
      }
      return 0;
    }
    
    // server.c
    
    #include <stdio.h>
    #include "readdev.c"
    #include "netsvr.c"
    #include "keyinterpreter.c"
    
    #define PORT 999
    
    int main(){
      int sockfd;  // socket file descriptor for listening to connections
      int keysockfd; // socket file descriptor for connection to client
      struct sockaddr_in clientdata;
      // request socket
      if(getsocket(&sockfd) != 0){
        printf("%s\n", " Error in function getsocket()");
        return -1;
      }
      else{
        printf("%s\n", " OK in function getsocket()");
      }
      // bind to port
      if(bindport(&sockfd, PORT) != 0){
        printf("%s\n", " Error in function bindport()");
        return -1;
      }
      else{
        printf("%s\n", " OK in function bindport()");
      }
      // listen to connection
      if(listconn(&sockfd) != 0){
        printf("%s\n", " Error in function listconn()");
        return -1;
      }
      else{
        printf("%s\n", " OK in function listconn()");
      }
      // accept connection
      if(acccon(sockfd, &keysockfd, &clientdata) != 0){  
        printf("%s\n", " Error in function acccon()");
        return -1;
      }
      else{
        printf("%s\n", " OK in function acccon()");
      }
      printf("%s\n", " Server is ready to send keystatus");
      printf("%s\n", " Connection established.");
      // Connection is now established. Ready to send data to client.
      while(1){
        int inst[2];
        int keystat;
        // Read out device
        getdata(inst);
        // Calculate key status
        keystat = calckeystat(inst);
        // Send key status
        sendkeystat(&keysockfd, keystat);
        printf("%s\n", " Keystatus sent.");
      }
      return 0;
    }
    

    Ich danke Euch schonmal im Voraus für Antworten, bin echt langsam am verzweifeln...

    Gruss
    allema



  • ich hab keine Lust den gesamten Code durchzulesen, aber mir fällt mir eins auf:

    was ist denn das für ein krankes Design, dass man .c Dateien mittels #include inkludiert?



  • Hallo allema

    Konnte bei einem kurzen Code-Überflug die Funktion WSAStartup nicht erkennen.
    Bevor Windows Socket Funktionen verwendet werden können muss diese Funktion erfolgreich aufgerufen werden...

    Viele Grüsse, Ratio



  • Ratio schrieb:

    Konnte bei einem kurzen Code-Überflug die Funktion WSAStartup nicht erkennen.
    Bevor Windows Socket Funktionen verwendet werden können muss diese Funktion erfolgreich aufgerufen werden...

    wie kommste darauf, dass er windows benutzt?
    🙂



  • Da habe ich den Code wohl wirklich zu kurz überflogen...

    Seine includierten-Headers deuten auf Linux/UNIX hin.

    Grüsse, Ratio



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum ANSI C in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • echt viel code zum eben mal lesen...
    Vielleicht hilft dir Wireshark http://www.wireshark.org (gibts auch in den standard Ubuntu Repositories) dabei herauszufinden, ob es am Client oder am Server liegt.
    Dann hättest du das Ganze (auch für uns) schonmal zumindest eingegrenzt...



  • netsvr.c, zeile 35:

    my_addr.sin_port = port;
    

    hier brauchst du noch die funktion htons für den port. htonl hast du schon für die adresse richtig verwendet.

    netsvr.c, zeile 66:

    *keysockfd = accept(sockfd, (struct sockaddr *) &clientdata, &sin_size);
    

    du verwendest hier die adresse auf einen zeiger, da clientdata ja schon ein zeiger ist. das tempcd kannst du schon weglassen, da du es eh nicht mehr verwendest.


Anmelden zum Antworten