[C Linux] printf schreibt nicht in Konsole

Anbrix

Mitglied
Hallo ^^

Ich habe folgendes kleines Programm im Interenet gefunden:

Code:
/* chat1d.c
 * Chat Server (Daemon) mit Threads fuer Linux
 * Autor: Andre Adrian
 * Version: 09jun2007
 *
 * Chat Server wartet auf TCP Port 51234 auf einen Verbindungsaufbau
 * von telnet Clients. Der Client sendet ASCII Meldungen an den Server.
 * Die Meldungen werden vom Server an alle anderen Clients gesendet.
 *
 * Aufruf Server:
 *  ./chat1d &
 *
 * Aufruf Client:
 *  telnet IP_Adresse_Server 51234
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>

/* Die Makros exit_if() und return_if() realisieren das Error Handling
 * der Applikation. Wenn die exit_if() Bedingung wahr ist, wird
 * das Programm mit Fehlerhinweis Datei: Zeile: Funktion: errno beendet.
 * Wenn die return_if() Bedingung wahr ist, wird die aktuelle Funktion
 * beendet. Dabei wird der als Parameter 2 angegebene Returnwert benutzt.
 */

#define exit_if(expr) \
if(expr) { \
  syslog(LOG_WARNING, "exit_if() %s: %d: %s: Error %s\n", \
  __FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno)); \
  exit(1); \
}

#define return_if(expr, retvalue) \
if(expr) { \
  syslog(LOG_WARNING, "return_if() %s: %d: %s: Error %s\n\n", \
  __FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno)); \
  return(retvalue); \
}

#define MAXLEN 1024
#define MAXFD 20

#define OKAY 0
#define ERROR (-1)

volatile fd_set the_state;
pthread_mutex_t mutex_state = PTHREAD_MUTEX_INITIALIZER;

int tcp_server_init(int port)
/* Server (listen) Port oeffnen - nur einmal ausfuehren
 * in port: TCP Server Portnummer
 * return: Socket Filedescriptor zum Verbindungsaufbau vom Client
 */
{
  int listen_fd;
  int ret;
  struct sockaddr_in sock;
  int yes = 1;

  listen_fd = socket(PF_INET, SOCK_STREAM, 0);
  exit_if(listen_fd < 0);

  /* vermeide "Error Address already in use" Fehlermeldung */
  ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  exit_if(ret < 0);

  memset((char *) &sock, 0, sizeof(sock));
  sock.sin_family = AF_INET;
  sock.sin_addr.s_addr = htonl(INADDR_ANY);
  sock.sin_port = htons(port);

  ret = bind(listen_fd, (struct sockaddr *) &sock, sizeof(sock));
  exit_if(ret != 0);

  ret = listen(listen_fd, 5);
  exit_if(ret < 0);

  return listen_fd;
}

int tcp_server_init2(int listen_fd)
/* communication (connection) oeffnen - fuer jeden neuen client ausfuehren
 * in listen_fd: Socket Filedescriptor zum Verbindungsaufbau vom Client
 * return: wenn okay Socket Filedescriptor zum lesen vom Client, ERROR sonst
 */
{
  int fd;
  struct sockaddr_in sock;
  socklen_t socklen;

  socklen = sizeof(sock);
  fd = accept(listen_fd, (struct sockaddr *) &sock, &socklen);
  return_if(fd < 0, ERROR);

  return fd;
}

int tcp_server_write(int fd, char buf[], int buflen)
/* Schreibe auf die Client Socket Schnittstelle
 * in fd: Socket Filedescriptor zum Schreiben zum Client
 * in buf: Meldung zum Schreiben
 * in buflen: Meldungslaenge
 * return: OKAY wenn Schreiben vollstaendig, ERROR sonst
 */
{
  int ret;

  ret = write(fd, buf, buflen);
  return_if(ret != buflen, ERROR);
  return OKAY;
}

void *tcp_server_read(void *arg)
/* Thread fuer einen CONNECT Port
 * Lese von der Client Socket Schnittstelle, schreibe an alle anderen Clients
 * in arg: Socket Filedescriptor zum lesen vom Client
 * return:
 */
{
  int rfd;
  char buf[MAXLEN];
  int buflen;
  int wfd;
 
  rfd = (int)arg;
  for(;;) {
    /* lese Meldung */
    buflen = read(rfd, buf, sizeof(buf));
    if (buflen <= 0) {
      /* End of TCP Connection */
      pthread_mutex_lock(&mutex_state);
      FD_CLR(rfd, &the_state);      /* toten Client rfd entfernen */
      pthread_mutex_unlock(&mutex_state);
      close(rfd);
      pthread_exit(NULL);
    }
   
    /* Meldung an alle anderen Clients schreiben */
    pthread_mutex_lock(&mutex_state);
    for (wfd = 3; wfd < MAXFD; ++wfd) {
      if (FD_ISSET(wfd, &the_state) && (rfd != wfd)) {
        tcp_server_write(wfd, buf, buflen);
      }
    }
    pthread_mutex_unlock(&mutex_state);
  }
  return NULL;
}

void loop(int listen_fd)
/* Server Endlosschleife - accept
 * in listen_fd: Socket Filedescriptor zum Verbindungsaufbau vom Client
 */
{
  pthread_t threads[MAXFD];
 
  FD_ZERO(&the_state);
  for (;;) {                    /* Endlosschleife */
    int rfd;
    void *arg;
   
    /* TCP Server LISTEN Port (Client connect) pruefen */
    rfd = tcp_server_init2(listen_fd);
    if (rfd >= 0) {
      if (rfd >= MAXFD) {
        close(rfd);
        continue;
      }
      pthread_mutex_lock(&mutex_state);
      FD_SET(rfd, &the_state);        /* neuen Client fd dazu */
      pthread_mutex_unlock(&mutex_state);
      arg = (void *) rfd;
      pthread_create(&threads[rfd], NULL, tcp_server_read, arg);
    }
  }
}

int main(int argc, char *argv[])
{
  /* Fehler Logging einschalten */
  openlog(NULL, LOG_PERROR, LOG_WARNING);

  /* open Chat as TCP server */
  loop(tcp_server_init(51234));

  return OKAY;
}


Da ich jetzt aber des Verständnis wegen ein wenig daran experimentieren möchte, habe ich printf() eingebaut.
Zum Beispiel driekt in die main():

Code:
int main(int argc, char *argv[])
{
  /* Fehler Logging einschalten */
  openlog(NULL, LOG_PERROR, LOG_WARNING);

  // Die hinzugefügte Ausgabe
  printf("Server running!");

  /* open Chat as TCP server */
  loop(tcp_server_init(51234));

  return OKAY;
}

Problem ist, dass ich es nicht in der Konsole angezeigt bekomme :S
Bei andren Programmen gehts einwandfrei.

Danke im Voraus!
MfG
 
*push*
War wohl noch etwas früh für den Post daher der Push ^^
Weiß keiner woran es liegen könnte ? :S =(
 
Hallo,

da der Ausgabepuffer wie auch der Name schon andeutet gepuffert wird, werden die Zeichen die du mit printf rausschiebst nicht gleich auf stdout angezeigt. Ein \n am Ende würde den Puffer lehren oder ein fflush(stdout) tuts auch...

Gruß,
RedWing
 
Allgemeine Frage:

würde nen fprintf(stdout.... daran was ändern? oder wird der auch gepuffert?
 
Hallo,
Allgemeine Frage:

würde nen fprintf(stdout.... daran was ändern? oder wird der auch gepuffert?

nein das würde nix ändern. Ausgabestreams in "normale" Dateien werden gewöhnlich auch gepuffert entweder bis \n oder bis jemand den Puffer explizit durch fflush leert.


Gruß,
RedWing
 
Zurück