Hei alle!
Jeg skal designe og implementere et sett med programmer som lar brukere logget på en vert å sende meldinger til hverandre.
Jeg har allerede startet med en messaging program som bør gjøres til en server og klient (Enn en meget for din hjelp Blowtorch). Jeg skal legge til dette programmet på en samordning program. Koordinatoren bør godta meldinger fra kunder og videresende dem til alle tilkoblede klienter. Jeg er også ventet å legge til en kommando til klienten som gjør den til loggen til en angitt tekstfil for alle mottatte meldinger.
Jeg tenker at en god måte å håndtere sin ville være å kapsle meldingen kø i en modul som kundene og koordinator kan ringe, men tingen er at jeg har ikke anelse om hvor du skal begynne! Vet u guys noen bøker eller nettsteder hvor jeg kan få eksempelkode og forklaringer fra? Jeg tror den eneste måten for meg å lære på er gjennom eksempler ...
PD Hvor mange. C-filer trenger jeg?
Enn en meget for hjelpen!
Oh, og her er mine messenger-programmer:
Code:
/*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;
}