Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : client-server versuch



ness
25-05-2005, 14:04
Ich versuche gerade, eine kleine clientserver applikation zu schreiben. Der server sieht so aus:
#include <iostream>
#include <string>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fstream>

const char* const fifoname="fifo";
const char* const pidfname="server.pid";

void sigusr(int)
{
std::string uname,upass;
char buffer[1];

int fd=open(fifoname,O_RDONLY);
ssize_t s;
while((s=read(fd,buffer,1))==1)
uname+=*buffer;
close(fd);
fd=open(fifoname,O_RDONLY);
while((s=read(fd,buffer,1))==1)
upass+=*buffer;
std::cout<<uname<<'\n'<<upass<<'\n'<<std::endl;
uname.clear();upass.clear();
};

void cleanup(int)
{
remove(fifoname);
remove(pidfname);
exit(0);
};

int main()
{
mkfifo(fifoname,S_IRUSR|S_IWUSR);
pid_t pid=getpid();
std::ofstream file(pidfname);
file<<pid<<std::endl;
file.close();

signal(SIGUSR1,sigusr);
signal(SIGTERM,cleanup);
signal(SIGINT,cleanup);

while(1)
pause();
return 0;
};(ich benutze mitunter die elementaren iofunktionen, wel das mit den fstreams irgendwie net klappt...). Das verhaletn sollte klar sein: sigusr senden, dann namedurch die fifo, fifo schließen, pass durch die fifo, fifo schließen. Wenn ich das "von hand" mache (server im Hintergrund starten, kill -USR1 `cat server.pid`, echo "name" >> fifo, echo "pass" >> fifo), klappt auch alles. Nun hab ich mal einen client geschrieben, der sieht so aus:
#include <iostream>
#include <string>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>

const char* const fifoname="fifo";
const char* const pidfname="server.pid";

pid_t get_serverpid()
{
unsigned upid;
std::ifstream file(pidfname);
file>>upid;
return static_cast<pid_t>(upid);
};

void send(const std::string& n,const std::string& p,pid_t pid)
{
kill(pid,SIGUSR1);
int fd;
fd=open(fifoname,O_WRONLY);
write(fd,n.c_str(),n.size());
close(fd);
fd=open(fifoname,O_WRONLY);
write(fd,p.c_str(),p.size());
close(fd);
};

int main()
{
pid_t spid=get_serverpid();
std::string uname,upass;
std::cout<<"Name: "<<std::flush;
std::cin>>uname;
std::cout<<"Passwort: "<<std::flush;
std::cin>>upass;
send(uname,upass,spid);
return 0;
};Wenn ich die eingaben über diesen mache, passiert erst mal nix, erst nach dem 2. Aufruf des clients erhalte ich eine ausgabe (name1pass1 name2pass2). Muss ich die files erst noch flushen oder so, bevor der server ein eof sieht? Wenn ja, wie?

sohler
25-05-2005, 17:13
Hallo,

ich habe Dein Server-Programm mal ausprobiert:

Verwende in main() mal etwas anderes als pause(), z.B. sleep(1).

Außerdem kommen in Deiner sigusr() Funktion die Eingaben immer an einem Stück, d.h. die erste while-Schleife bekommt alles. Du müsstest also das eingelesene Zeichen überprüfen, ob es sich um ein '\n' handelt und dann die erste while-Schleife verlassen.

Gruß,
S. Ohler