Hej alla!
Jag ska utforma och genomföra en uppsättning program som gör att användare loggat in på en värd att skicka meddelanden till varandra.
Jag började redan med en messaging program som bör göras av en server och en klient (Thanx a lot for your help Blowtorch). Jag ska lägga det här programmet till en samordning program. Samordnaren bör acceptera meddelanden från kunder och vidarebefordra dem till alla bifogade klienter. Jag förväntas också lägga till ett kommando till kunden som gör det möjligt att logga in till en angiven textfil för alla mottagna meddelanden.
Jag tänker på att ett bra sätt att hantera sina vore att sammanfatta budskapet kö i en modul som klienterna och samordnare kan ringa, men saken är den att jag har inte ens en aning om var man ska börja! Do u guys know några böcker eller hemsidor där jag kan få exempelkod och förklaringar från? Jag tror att det enda sättet för mig att lära är genom exempel ...
PD Hur många. C-filer behöver jag?
Thanx a lot for your help!
Åh, och här är mina Messenger-program:
Kod:
/*q.h*/
#ifndef Q_H
#define Q_H
#define QKEY ftok("q.h",1)
#define MSGSZ 128
#ifdef DEBUG
#define DEBUG_PRINT(...) fprintf(stderr,__VA_ARGS__)
/* this __VA_ARGS__ thing allows a macro to
take a varialble number of arguments */
#else
#define DEBUG_PRINT(...) /* __VA_ARGS__ */
#endif
int init_queue();
int exchange_pids();
void remove_queue();
int send_mesg(char*,int);
int send_mesg_signal(char*,int);
int recv_mesg(char*,int);
#endif
/*signalmsg.c*/
#include<signal.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include"q.c"
#include"q.h"
int cnt;
void hndlr(int);
main()
{
struct sigaction buf;
char msg[MSGSZ];
int stop=0,n;
sigfillset(&buf.sa_mask);
buf.sa_flags=0;
buf.sa_handler=hndlr;
sigaction(SIGUSR1,&buf,NULL);
sigaction(SIGINT,&buf,NULL);
init_queue();
exchange_pids();
while(!stop)
{
printf("\nEnter message: ");
while (-1 == (n=read(0,msg,MSGSZ-1) ))
{
if (errno != EINTR )
{
perror("read");
send_mesg("bye\n",0);
exit(1);
}
for(;cnt>0;cnt--)
{
recv_mesg(msg,0);
printf("\nReceived Message: %s\n", msg);
if (0==strcmp(msg,"bye\n"))
{
remove_queue();
exit(0);
}
}
printf("\nEnter message: ");
}
msg[n]=0;
send_mesg_signal(msg,0);
if (0==strcmp(msg,"bye\n"))
stop=1;
}
return 0;
}
void hndlr(int sig)
{
DEBUG_PRINT("Caught signal: %d\n",sig);
switch(sig)
{
case SIGUSR1: DEBUG_PRINT("USR1 branch\n");
cnt++;
break;
case SIGINT: DEBUG_PRINT("SIGINT branch\n");
send_mesg_signal("bye\n",0);
exit(0);
break;
default: fprintf(stderr,"Yikes how did I get here?!!!\n");
exit(1);
}
}
/*q.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<unistd.h>
#include<signal.h>
#include<errno.h>
#include"q.h"
struct mymsg
{
long mtype;
char mtext[MSGSZ];
};
static int qid;
static int channel_no;
static pid_t remote_pid;
void remove_queue()
{
msgctl(qid,IPC_RMID,0);
}
int init_queue()
{
char msg[MSGSZ];
int rv;
if( -1 != ( qid = msgget(QKEY,IPC_CREAT|IPC_EXCL|0600) ))
{
/* am entity A using channel 1 */
channel_no=1;
DEBUG_PRINT("Am entity A\n");
return 0;
}
if ( errno != EEXIST )
{
perror("MSGGET:");
return -1;
}
if (-1 != ( qid = msgget(QKEY,IPC_CREAT|0600) ))
{
/* am entity B using channel 2 */
channel_no=2;
DEBUG_PRINT("Am entity B\n");
return 0;
}
perror("MSGGET:");
return -1;
}
int exchange_pids()
{
char msg[MSGSZ];
if(channel_no==1)
{
/* sending PID to other end */
sprintf(msg,"%d",getpid());
send_mesg(msg,0);
DEBUG_PRINT("My pid is %s\n",msg);
/* grab pid from other end */
recv_mesg(msg,0);
sscanf(msg,"%d",&remote_pid);
DEBUG_PRINT("Received PID is %s\n",msg);
}
else
{
/* grab pid from other end */
recv_mesg(msg,0);
sscanf(msg,"%d",&remote_pid);
DEBUG_PRINT("Received PID is %s\n",msg);
/* sending PID to other end */
sprintf(msg,"%d",getpid());
send_mesg(msg,0);
DEBUG_PRINT("My pid is %s\n",msg);
}
return remote_pid;
}
int recv_mesg(char *msg, int nb)
{
struct mymsg m;
int options=0,len;
int recv=((channel_no==1)?2:1);
DEBUG_PRINT("Receiving on %d\n",recv);
if (nb) options|=IPC_NOWAIT;
if( -1==(len=msgrcv(qid,&m,MSGSZ,recv,options)))
return -1;
strcpy(msg,m.mtext);
return len;
}
int send_mesg(char* msg,int nb)
{
struct mymsg m;
int options,len;
m.mtype=channel_no;
strcpy(m.mtext,msg);
len=strlen(msg)+1;
options=0;
if (nb) options|=IPC_NOWAIT;
DEBUG_PRINT("Sending type %d\n",m.mtype);
return msgsnd(qid,&m,len,options);
}
int send_mesg_signal(char*msg,int nb)
{
int rv;
rv=send_mesg(msg,nb);
kill(remote_pid,SIGUSR1);
return rv;
}