Server - Client Problem mit select()

S

sniper

Jungspund
Hallo,
ich habe ein Programm, besser gesagt 2 Programme die miteinander über ein Netzwerk mit Hilfe von pipes kommunizieren sollen, also ein Server und ein Client Programm.
Sie sollen sich nur einfach Nachrichten schicken können. Das klappt bis jetzt auch ziemlich gut nur das Problem ist das ich blockierende Funktionen benutze und deswegen muss jedes mal wenn einer eine Nachricht schickt erstmal auf die Antwort gewartet werden um wieder was schicken zu können. Also man kann nicht z.B. 2-3-4 Nachrichten hintereinander von Server zum Client (oder umgekehrt) geschickt werden. Deswegen wollte ich das ganze mit eine nichtblockierende Funktion lösen – mit select() z.B..
Aber irgendwie krieg ich das nicht hin, ich bin schon langsam am verzweifeln. ;(
Hilfe!!!

Dies sind meine 2 Programme in der Version wo sie noch funktionier haben.

Server
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF 1024

int main (void) {
  int create_socket, new_socket;
  socklen_t addrlen;
  char *buffer = (char *) malloc (BUF);
  ssize_t size;
  struct sockaddr_in address;
  const int y = 1;

  if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
    printf ("Socket wurde angelegt\n");

  setsockopt( create_socket, SOL_SOCKET,
              SO_REUSEADDR, &y, sizeof(int));

  address.sin_family = AF_INET;
  address.sin_addr.s_addr = INADDR_ANY;
  address.sin_port = htons (15000);
  if (bind ( create_socket,(struct sockaddr *) &address, sizeof (address)) != 0) {
    printf( "Der Port ist nicht frei - belegt!\n");
  }
  listen (create_socket, 5);
  addrlen = sizeof (struct sockaddr_in);

  for (;;) {
     new_socket = accept ( create_socket,(struct sockaddr *) &address, &addrlen );
     if (new_socket > 0)
         printf ("Ein Client (%s) ist verbunden ...\n", inet_ntoa (address.sin_addr));
     do {
        printf ("Nachricht zum Versenden: ");
        fgets (buffer, BUF, stdin);
        send (new_socket, buffer, strlen (buffer), 0);
        size = recv (new_socket, buffer, BUF-1, 0);
        if( size > 0)
           buffer[size] = '\0';
           printf ("Nachricht empfangen: %s\n", buffer);
     } while (strcmp (buffer, "quit\n") != 0);
     close (new_socket);
  }
  close (create_socket);
  return EXIT_SUCCESS;
}

Client
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF 1024

int main (int argc, char **argv) {
  int create_socket;
  char *buffer = (char *) malloc (BUF);
  struct sockaddr_in address;
  int size;

  if( argc < 2 ){
     printf("Usage: %s ServerAdresse\n", *argv);
     exit(EXIT_FAILURE);
  }

  if ((create_socket = socket (AF_INET, SOCK_STREAM, 0)) > 0)
    printf ("Socket wurde angelegt\n");

  address.sin_family = AF_INET;
  address.sin_port = htons (15000);
  inet_aton (argv[1], &address.sin_addr);

  if (connect ( create_socket,(struct sockaddr *) &address,sizeof (address)) == 0)
      printf ("Verbindung mit dem Server (%s) hergestellt\n", inet_ntoa (address.sin_addr));
  do {
      size = recv(create_socket, buffer, BUF-1, 0);
      if( size > 0)
         buffer[size] = '\0';
      printf ("Nachricht erhalten: %s\n", buffer);
      if (strcmp (buffer, "quit\n")) {
         printf ("Nachricht zum Versenden: ");
         fgets (buffer, BUF, stdin);
         send(create_socket, buffer, strlen (buffer), 0);
      }
  } while (strcmp (buffer, "quit\n") != 0);
  close (create_socket);
  return EXIT_SUCCESS;
}
 
krass ich hab dich für nen c noob gehalten weggen dem tread nit den getch()
aber jetzt kommst du da mit nem kleinen instant messenger an
also hey respeckt
*hab noch viel zu lernen*
MFG MoE
 
Zuletzt bearbeitet:
krass ich hab dich für nen c noob gehalten weggen dem tread nit den getch()
aber jetzt kommst du da mit nem kleinen instant messenger an
also hey respeckt

Naja ein Programmierprofi bin ich auch nicht. Das mit der getchar() hatte ich Probleme weil ich mehrere Abfragen hatte und es ist immer Müll in der Puffer geblieben. Und diese eine Funktion um den Puffer zu leeren funktionier bei Linux nicht immer, also bei mir überhaupt nicht.

Nun aber wieder zum Thema: :oldman

Die select funktion;
int select(int nfds, fdset *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

Mit dem ersten Parameter nfds gibt man die Größe der folgenden Menge an.
Die nächsten drei Parameter sind Zeiger auf die fd_sets, welche zum Lesen, Schreiben oder auf Ausnahmen getestet werden.

Mit readfds wird überprüft, ob auf den (Socket-)Deskriptoren Daten zum Lesen vorhanden sind.
Mit writefds wird die Beschreibbarkeit von (Socket-)Deskriptoren überprüft – sprich, ob ein Deskriptor bereit ist, eine Ausgabe anzunehmen.
Sofern man einen Parameter nicht verwenden will, kann man für ihn eine NULL angeben.

Wenn ich nur fdset *readfds verwende ist mir alles klar aber ich verstehe nicht fdset *writefds. Wenn ich z.B. fgets schreibe dann wartet das Programm bis ich irgendwas eingebe. Woher soll das Programm wiesen wann ich eine Eingabe machen will? :think: Kann mir da jemand weiterhelfen??

Danke in voraus.
 

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

Server und Client für TCP und UDP

Prozesskommunikation mit PIPES - wie funktioniert das?

C HTTP request

[C] Speicherzugriffsfehler mit malloc

Zurück
Oben