Hallo ^^
Ich habe folgendes kleines Programm im Interenet gefunden:
Da ich jetzt aber des Verständnis wegen ein wenig daran experimentieren möchte, habe ich printf() eingebaut.
Zum Beispiel driekt in die main():
Problem ist, dass ich es nicht in der Konsole angezeigt bekomme :S
Bei andren Programmen gehts einwandfrei.
Danke im Voraus!
MfG
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