IPC using message queue in C: Error in receiving - c

I am implementing message queue in C linux. I am sending an integer = 17 and receiving integer = 0. Please see below and let me know what's wrong with my msgsnd and msgrcv functions.
Please give attention to this: will rbuf store data in rbuf->m->msglen or in rbuf->mtype.
In sending process
msgsnd(msqid, sbuf,sizeof(int), 0);
printf("\nmsglen = %d",rbuf->m->msglen); // 17
In receiving process. Both have same msqid. I have verified it.
msgrcv(msqid, rbuf, sizeof(int), 1, 0);
printf("\nmsglen = %d",rbuf->m->msglen); // 0
//msqid=98305, some valid id
here is my struct definations defined in another file.
typedef struct message1
{
int msglen;
unsigned char *cp;
}msg1;
typedef struct msgbuf
{
long mtype;
msg1 *m;
} message_buf;

You are sending a message which contains a pointer to your message1 struct. The receiving process dereferences that pointer, but in that process it does not point to the same thing. In fact I am surprised you didn't get a segfault.
You should define msgbuf like this:
typedef struct msgbuf
{
long mtype;
msg1 m;
} message_buf;
So that the msg1 struct is contained within the msgbuf rather than pointed to by it.
Also, the size you need to specify is sizeof(message_buf), not sizeof(int).

//header files
#include"msgbuf.h" //where I have put my structures
#define AUTOMATIC 1
#define USER_DATA 2
int main()
{
int msgflg = IPC_CREAT | 0666,ch,len=0;
size_t msgsize = 0;
int msqid;
key_t key;
message_buf *sbuf;
char ans;
char *data;
key = ftok("/home/user",15);
printf("Do you want to send messages\t");
scanf("%c",&ans);
getchar();
if (((ans=='y' || ans=='Y') && (msqid = msgget(key, msgflg )) ==-1))
{ perror("msgget");
exit(1);
}
else
fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);
while(ans=='y' || ans=='Y')
{
printf("\n1. Automatic data\n2. Enter data\n3. Exit\nEnter your choice\t");
scanf("%d",&ch);
getchar();
switch(ch)
{
case AUTOMATIC: len=strlen("Did you get this?");
sbuf=malloc(len+sizeof(int));
memset(sbuf, 0, sizeof(message_buf));
sbuf->m=malloc(len+sizeof(int));
memset(sbuf->m, 0, sizeof(msg1));
sbuf->m->msglen=len;
sbuf->m->cp=malloc(sizeof(len));
strncpy(sbuf->m->cp, "Did you get this?",strlen("Did you get this?"));
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
break;
case USER_DATA: printf("\nEnter data\t");
fflush(stdout);
len = getline(&data, &msgsize, stdin);
sbuf=malloc(len+sizeof(int));
memset(sbuf, 0, sizeof(message_buf));
sbuf->m=malloc(len+sizeof(int));
memset(sbuf->m, 0, sizeof(msg1));
strcpy(sbuf->m->cp, data);
sbuf->m->cp[strlen(sbuf->m->cp)]='\0';
sbuf->m->msglen=len;
break;
case 3: msgctl(msqid, IPC_RMID, NULL);
printf("\nQueue with q id = %d is removed\n",msqid);
exit(1);
default:printf("\nTRY AGAIN\t");
scanf("%c",&ans);
getchar();
}
printf("\nmsglen = %d\nmsgcp= %s",sbuf->m->msglen,sbuf->m->cp);
/* Send a message */
sbuf->mtype=1;
if (msgsnd(msqid, sbuf,2*sizeof(int), 0) < 0)
{
printf("Msg q id= %d\nMsg type= %d\nMsg Text %s\nMsg Len= %d\n", msqid, sbuf->mtype, sbuf->m->cp,sbuf->m->msglen);
perror("msgsnd");
exit(1);
}
else
printf("\nMessage: %s\n Sent\n", sbuf->m->cp);
}
msgctl(msqid, IPC_RMID, NULL);
printf("\nQueue with q id = %d is removed\n",msqid);
return 0;
}
Now Receiving code
//header files
#include"msgbuf.h"
int main()
{
int msqid;
key_t key;
int msgflg = 0666;
message_buf *rbuf;
int msg_len_rcvd=0;
rbuf=malloc(150);
rbuf->m=malloc(100);
key = ftok("/home/user",15);
if ((msqid = msgget(key, msgflg)) ==-1)
{
perror("msgget");
exit(1);
}
printf("\n\n%d\n",msqid);
/* Receive an answer of message type 1. */
while(1)
{
if ( (msg_len_rcvd=msgrcv(msqid, rbuf, 2*sizeof(int), 1, 0)) < 0)
{
perror("msgrcv");
exit(1);
}
else
{
printf("\n Number of bytes received:: %d", msg_len_rcvd);
printf("\nmtype1 = %d",rbuf->mtype);
printf("\nmsglen= %d",rbuf->m->msglen);
}
break;
}
return 0;
}

Related

Message Queue with C passing 2 numbers and 1 operator but getting error at server file

In message queue I have created server.c and client.c. Created a structure with 2 numbers, 1 char for operator and 1 is for message type.
The program is about to send the 2 numbers and an operator to the server and from server execute that and sent back the answer of that expression to the client.
But i am continuously getting following error
Identifier Removed
I don't know where I am doing wrong.
header.h
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
client.c
#include "./header.h"
#define KEY 777
#define SIZE 50
struct message
{
long type;
double no1, no2;
char operator;
char ans[SIZE];
};
int main()
{
struct message msg;
int qid = msgget((key_t)KEY, IPC_CREAT | 0666);
if (qid < 0)
perror("Error creating queue");
else
{
printf("Enter no1 : ");
scanf("%lf", &msg.no1);
printf("Enter no2 : ");
scanf("%lf", &msg.no2);
getc(stdin);
printf("Enter operator : ");
msg.operator= getchar();
msg.type = 1;
if (msgsnd(qid, &msg, sizeof(msg) - sizeof(msg.type), IPC_NOWAIT) < 0)
perror("Error to write data");
else
{
// if (msgrcv(qid, &msg, sizeof(msg.ans), 2, 0) < 0)
// perror("error to read response");
// else
// {
// printf("%s\n", msg.ans);
// }
}
msgctl(qid, IPC_RMID, NULL);
}
return 0;
}
`
server.c
#include "./header.h"
#define KEY 777
#define SIZE 50
struct message
{
long type;
double no1, no2;
char operator;
char ans[SIZE];
};
int main()
{
struct message msg;
int qid = msgget((key_t)KEY, IPC_CREAT | 0666);
if (qid < 0 && errno != EEXIST)
perror("Error creating queue");
else
{
if (msgrcv(qid, &msg, sizeof(msg) - sizeof(msg.type), 1, 0) < 0)
perror("Reading error");
else
{
printf("%lf\n", msg.no1);
int flag = 0;
double ans = 0;
switch (msg.operator)
{
case '+':
ans = msg.no1 + msg.no2;
break;
case '-':
ans = msg.no1 - msg.no2;
break;
case '/':
ans = msg.no1 / msg.no2;
break;
case '*':
ans = msg.no1 * msg.no2;
break;
default:
flag = 1;
snprintf(msg.ans, sizeof(msg.ans), "Invalid Operator");
break;
}
printf("final decision\n");
if (flag == 0)
{
snprintf(msg.ans, sizeof(msg.ans), "Total = %lf", ans);
}
printf("%s\n", msg.ans);
// msg.type = 2;
// if (msgsnd(qid, &msg, sizeof(msg), 0) < 0)
// perror("Error to reply");
}
msgctl(qid, IPC_RMID, NULL);
}
return 0;
}

Message queue - No proper response

*I'm using message queues for sending and receiving messages but some parameters in the the structure msqid_ds no giving proper values why it happens?
*Time of last message send=1525240214- why this is showing junk values?
struct mesg_q
{
char msg_txt[100];
long msg_typ;
};
int main()
{
int msgid;
key_t key;
char buffer[100];
struct mesg_q msgq;
struc answerst msqid_ds info;
// key = ftok("/home/yash72/krishna/thread_test/msgq.text", 65);
msgid=msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid== -1)
{
printf("msgget failed\n");
return -1;
}
while(1)
{
printf("Text Message\n");
fgets(msgq.msg_txt,100,stdin);
if(msgsnd(msgid,&msgq,100,0)==-1)
{
printf("Send failed\n");
return -1;
}
else
{
printf("Message send\n");
}
msgctl(msgid, IPC_STAT, &info);
printf("Time of last message send=%d\n",info.msg_stime);
printf("uid=%d\n",info.msg_perm.uid);
}
}
OUTPUT:
Text Message
qwerty
Message send
Time of last message send=1525240214 // Why this is showing junk?
uid=0
Text Message
Receiver code:
Reason for junk values from this code?
struct mesg_q
{
char msg_txt[100];
long msg_typ;
};
int main()
{
int msgid;
char buffer[100];
long int rec_buff=0;
key_t key;
struct mesg_q msgq;
struct msqid_ds info;
// key = ftok("/home/yash72/krishna/thread_test/msgq.text", 65);
msgid=msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
printf("Msgget failed\n");
return -1;
}
while(1)
{
if(msgrcv(msgid,&msgq,100,rec_buff,0)==-1)
{
printf("Mesg recv failed\n");
return -1;
}
else
{
printf("Mesg Recvd\n");
}
printf("Recvd mesg=%s\n",msgq.msg_txt);
msgctl(msgid, IPC_STAT, &info);
printf("Num:of bytes on queue= %d\n", info.msg_cbytes);
printf("num:of messages on queue=%d\n", info.msg_qnum);
printf("Max bytes on queue=%d\n", info.msg_qbytes);
printf("Time of last message recvd=%d\n",info.msg_rtime);
}
}
OUTPUT;
Number of bytes on queue= 0
number of messages on queue=0
Maximum bytes on queue=16384
Time of last message received=1525240214
what is the reason foe this incorrect values from struct msqid_ds ?
First of all you should know why to use message queue IPC, I assume before using message queue, you have gone through FIFO. In FIFO what is condition for the processes to communicate each other ? that both process should be alive while communicating.
To avoid above problem of FIFO you are using message queue, as in MQ you can put data at one time and can read at anytime, for that you have to specify the mtype i.e with what mtype process_1 is sending the data and with what mtype process_2 is receiving the data.
From the manual page of msgsnd
struct msgbuf {
long mtype; /* message type, must be > 0, I'm talking baout this */
char mtext[1]; /* message data */
};
so in both the process(reader & sender) specify the mtype
msgq.msg_typ = 1; /*specify this in both process */
Secondly, Time of last message send=1525240214- why this is showing junk values ? => Its not junk data, its the time in seconds from EPOCH time, use ctime() to print in human readable format.
sender.c
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdint.h>
struct mesg_q {
char msg_txt[100];
long msg_typ;
};
int main(void) {
int msgid;
struct mesg_q msgq;
struct msqid_ds info;
msgid=msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid== -1) {
printf("msgget failed\n");
return -1;
}
while(1) {
printf("Text Message\n");
fgets(msgq.msg_txt,sizeof(msgq.msg_txt),stdin);
/* with what msg_type you are sending, you didn't mention ? mention it */
msgq.msg_typ = 1; /* I am sending with msg_type 1 */
if(msgsnd(msgid,&msgq,sizeof(msgq),msgq.msg_typ)==-1) {
printf("Send failed\n");
return -1;
}
else {
printf("Message send\n");
}
msgctl(msgid, MSG_STAT, &info);
printf("Time of last message send = %jd\n",(intmax_t)info.msg_stime);/* use the correct format specifier */
/* what ever time info.msg_stime printing, its not junk, its seconds from EPOCH, use ctime() to print in readable format */
printf("uid = %d\n",info.msg_perm.uid);
}
return 0;
}
receiver.c
struct mesg_q {
char msg_txt[100];
long msg_typ;
};
int main(void ){
int msgid;
long int rec_buff=0;
struct mesg_q msgq;
struct msqid_ds info;
msgid=msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1) {
printf("Msgget failed\n");
return -1;
}
while(1) {
/* with what msg_typ you are reciving, you have to mention ? u didn't */
msgq.msg_typ = 1;
if(msgrcv(msgid,&msgq,sizeof(msgq),rec_buff, msgq.msg_typ)==-1) {
printf("Mesg recv failed\n");
return -1;
}
else{
printf("Mesg Recvd\n");
}
printf("Recvd mesg=%s\n",msgq.msg_txt);
msgctl(msgid, MSG_STAT, &info);
/* enable compiler warning, and use correct format specifier */
printf("Num:of bytes on queue= %u\n", (int)info.msg_cbytes);
printf("num:of messages on queue=%d\n", (int)info.msg_qnum);
printf("Max bytes on queue=%d\n", (int)info.msg_qbytes);
printf("Time of last message recvd=%jd\n",(intmax_t)info.msg_rtime);
}
return 0;
}

Can't delete old messages in message queue C

I have created a msq to let two processes communicate to one another. The problem is that I'm having some issues since after a couple of time that I run my code some of the old messages of the previous executions show up. This bothers me because I need to perform controls on the current data and cant do it because of this. I tried irpcm -q msqid but it does not do anything except shutting down my program the next time I run it. I even tried hardcoding some keys thinking that it would help but nothing. Also tried to msgctl(msqid, IPC_RMID, 0) after I finished using the queue but nothing. Hope you can help me out and thanks in advance.
Here is my code:
sender.c
#define MAXSIZE 1024
struct msgbuf
{
long mtype;
char mtext[MAXSIZE];
};
void die(char *s)
{
perror(s);
exit(1);
}
int msqid1;
int msgflg = IPC_CREAT | 0666;
key_t keymq1;
struct msgbuf sbuf;
size_t buflen;
keymq1 = 668;
sbuf.mtype = 1;
if ((msqid1 = msgget(keymq1, msgflg )) < 0)
die("msgget");
sbuf.mtype = 1;
strcpy(sbuf.mtext,"my message");
buflen = strlen(sbuf.mtext) + 1 ;
if (msgsnd(msqid1, &sbuf, buflen, IPC_NOWAIT) < 0)
{
printf ("%d, %ld, %s, %zu\n", msqid1, sbuf.mtype, sbuf.mtext, buflen);
die("msgsnd");
}
else {
printf("Message sent\n");
}
receiver.c
#define MAXSIZE 1024
struct msgbuf
{
long mtype;
char mtext[MAXSIZE];
};
void die(char *s)
{
perror(s);
exit(1);
}
int msqid;
key_t keymq1;
struct msgbuf rcvbuffer;
keymq1 = 668;
if ((msqid = msgget(keymq1, 0666)) < 0)
die("msgget()");
if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0)
die("msgrcv");
printf("Message received: %s\n", rcvbuffer.mtext);
To delete message queue with message queue Id use
ipcrm -q id
or delete the message queue using key value as
ipcrm -Q key_num
From man page "In order to delete such objects, you must be superuser, or the cre‐
ator or owner of the object."
Finally you can delete the message queue using IPC_RMID flag in msgctl() call as
main()
{
int total_mq,i,msqid;
struct msqid_ds ds; //dataStructure holding complete info for indexed message que
struct msginfo msginfo; //general buff copying data from MSG_INFO, has info of how many message que present right now
/* Obtain size of kernel 'entries' array */
total_mq = msgctl(0, MSG_INFO, (struct msqid_ds *) &msginfo); //copy kernel MSGQ_INFO to local buff
//returns count of active message Q
if (total_mq < 0)
{
perror("msgctl");
return 0;
}
printf("no of active message queue(KEY) : %d\n", total_mq+1);
/* Retrieve meaasge Queue id's */
for (i = 0; i <= total_mq; i++)
{
msqid = msgctl(i, MSG_STAT, &ds); //from each index using MSG_STAT -> ds, return msgqid
if (msqid <0 )
{
perror("msgctl");
return 0;
}
/* using msgqid remove the message queue */
if ( msgctl(msqid,IPC_RMID,0) < 0 )
{
perror("msgctl");
return 0;
}
}
printf("all message queues removed\n");
return 0;
}
before running above code, create some message queues and then delete those.

Segmentation fault due to file descriptor in multi threaded client

I have created a client-server file sharing system with multi threading. The client code is working correctly for a single client. When I increase the number of threads in client, segmentation fault is occurred in server code.
When I executed the code on gdb, it shows the error segmentation fault occurred, no such file or directory. Is this because of the threads sharing file descriptor? How to resolve the segmentation fault?
----------edit-----------
I considered all your suggestions. Most of the errors are resolved, but when I try to send a >10mb file, some send-recv call does not execute fully while sending it out with threads(It works fine with a single thread). I believe this is the reason memory leakage is happening and ultimately results in segmentation fault(file pointers not closed). The same is happening in gdb.
How to resolve this send receive blocking error?
client code
#include <time.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<stdio.h>
#include <stdlib.h>
#include<pthread.h>
#include <semaphore.h>
#define PORT 8029
#define SIZE 1024
#define SERVER_ADDR "192.168.43.158" //"10.15.36.112"
//defining number of threads
struct ser_data
{
int sockfd;
int n;
};
void *client_req(void * data){
// printf("inside thread\n");
//sleep(1);
int s,c,n,read_size,r;
//login_id and password of the user
//array to choose file names randomly
//char f_name[20][20]={"f0.txt","f1.txt","f2.txt","f3.txt","f4.txt","f5.txt","f6.txt","f7.txt","f8.txt","f9.txt","f10.txt\0","f11.txt\0","f12.txt\0" ,"f13.txt\0","f14.txt\0","f15.txt\0","f16.txt\0","f17.txt\0","f18.txt","f19.txt"};
//socket address for client and server
//used for generation of random no
time_t t;
struct sockaddr_in cli,serv;
FILE *f;
char fname[SIZE]="file_cli/";
char f_name[SIZE];
char login_id[21], pswd[21], choice[2];
//msg_cli_rec= message recieved form server
char msg_cli_rec[SIZE];
//msg_cli_send =message sent by client
char msg_cli_send[SIZE];
time_t start, stop;
int brk=0;
start = time(NULL);
s=socket(AF_INET,SOCK_STREAM,0);
bzero((char*)&serv,sizeof(cli));
cli.sin_family=AF_INET;
cli.sin_port=htons(PORT);
cli.sin_addr.s_addr = inet_addr(SERVER_ADDR);
connect(s,(struct sockaddr*)&cli,sizeof(cli));
//printf("\nConnected with server");
strcpy(choice, "1");
/*msg_cli_rec = (char *) malloc(1000* sizeof(char));
msg_cli_send = (char *) malloc(1000* sizeof(char));*/
//if user wants to login
if(strcmp(choice,"1")==0)
{
strcpy(login_id, "prach");
send(s, login_id, sizeof(login_id), 0);
strcpy(pswd, "prach");
send(s, pswd, sizeof(pswd), 0);
}
//making default choice download 1
do {
strcpy(choice, "1\0");
strcpy(msg_cli_send, choice);
//send(s, choice, sizeof(choice), 0);
send(s,msg_cli_send,sizeof(msg_cli_send),0);
//random number generation
srand((unsigned) time(NULL));
//r=((unsigned)rand()*(i++))%20;
r=15;
if(strcmp(choice,"1")==0)
{
/*if(recv(s, msg_cli_rec, sizeof(msg_cli_rec), 0))
{
//if((strcmp("end",msg_cli_rec))==0)break;
printf("\n%s", msg_cli_rec);
}*/
/*printf("\nEnter the file name you want:");
scanf("%s", msg_cli_send);*/
// to select file name with index of the random number
sprintf(f_name,"file (%d).txt",r);
strcpy(msg_cli_send, "");
strcpy(msg_cli_send,f_name);
// printf("\n%s",msg_cli_send);
// printf("\n rand =%d\n", r );
send(s,msg_cli_send,sizeof(msg_cli_send),0);
// printf("\nThe received file content is:");
//receiving the file names
f = fopen(strcat(fname,f_name),"w");
bzero( msg_cli_rec, sizeof(msg_cli_rec));
while((recv(s, msg_cli_rec, sizeof(msg_cli_rec), 0)> 0)&&(*msg_cli_rec!='\0'))
{//fflush(stdout);
if((strcmp("quit",msg_cli_rec))==0)break;
fprintf(f, "%s", msg_cli_rec);
//printf("\n%s", msg_cli_rec);
bzero( msg_cli_rec, sizeof(msg_cli_rec));
}
// printf("File recieved");
fclose(f);
strcpy(fname,"\0" );
//sem_post(&sem);
}
stop = time(NULL);
// printf("\n%s\n", ctime(&stop));
//printf("%ld", (stop-start));
//set the timer to 300 seconds
}while(*choice == '1' && (stop-start)<10);
//tell the server that we are done with sending files
strcpy(choice, "0");
send(s, choice, sizeof(choice), 0);
printf("%ld\n", (stop-start) );
/* free(msg_cli_rec);
free(msg_cli_send);*/
close(s);
//pthread_exit(NULL);
}
int main()
{
int N_Threads=2, count =0;
struct ser_data data;
/*while(N_Threads<=2)
{
pthread_t t;
pthread_create( &t , NULL , client_req , NULL);
N_Threads++;
if ( ! pthread_detach(t) )
printf("Thread detached successfully !!!\n");
//pthread_join(t, NULL);
}*/
while(count != N_Threads){
pthread_t handle;
count = count+1;
data.sockfd = count;
if(pthread_create(&handle, NULL, client_req,(void *)&data)<0)
error("Error creating thread");
else
printf("Thread allocation successful for fd: %d\n",data.sockfd);
}
pthread_exit(NULL);
}
server code
#include <time.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<dirent.h>
#include <mysql/mysql.h>
#include <semaphore.h>
#define PORT 8029
#define SIZE 1024
#define QUERY_SIZE 200
#define N_Threads 5
#define SERV_ADDR "192.168.43.158"
clock_t start, stop;
//login id and password of the user
int file_id=1;
/*Database variables*/
MYSQL *db_conn;
char *db_server = "localhost";
char *db_user = "root";
char *db_password = "root";
char *database = "file_db";
//for synchronization while accessing the db
sem_t sem;
/* A function which generates the and returns login query statement*/
char* query_login(char *query, char *login_id, char *pswd)
{
//generating query
strcpy(query,"SELECT * FROM user_info WHERE user_id='");
strcat(query, login_id);
strcat(query, "' AND pswd='");
strcat(query, pswd);
strcat(query, "'");
return query;
}
/* A function which generates and returns the register query statement*/
char* query_register(char *query, char *login_id, char *pswd)
{
strcpy(query, "INSERT INTO user_info VALUES ( '");
strcat(query, login_id);
strcat(query, "', '");
strcat(query, pswd);
strcat(query, "' )");
return query;
}
void *connect_client(void *socket)
{ int sock=*(int*)socket;
printf("\nFD %d",sock);
char msg_c_r[SIZE], msg_s_s[SIZE];
//for the choice given to the user to login or register
char choice='0';
char msg_serv_send[SIZE],msg_serv_rec[SIZE];
char msg_cli_rec[SIZE];
char fpath[SIZE] = "file_serv/";
char fname[SIZE];
int read_size;
int num_fields=0;
char * line = NULL;
size_t len = 0;
ssize_t read;
MYSQL_ROW row;
MYSQL_RES *db_res;
char login_id[21], pswd[21];
FILE *f;
FILE *fc;
char name[SIZE];
char query1[SIZE];
char query[QUERY_SIZE];
/*locking the database for mutual exclusion*/
//sem_wait(&sem);
//executing a query
choice = '1';
strcpy(query, "\0");
switch(choice)
{
//1 = login
case '1':
/*to find the login id and password of the user*/
bzero(login_id, sizeof(login_id));
recv(sock, login_id, sizeof(login_id), 0);
bzero(pswd, sizeof(pswd));
recv(sock, pswd, sizeof(pswd), 0);
printf("The login id is: %s\nThe Password is: %s\n", login_id, pswd);
//lock for accessing db in mutual exclusion
sem_wait(&sem);
query_login(query, login_id, pswd);
//checking the details given by client
if (mysql_query(db_conn, query)!=0) {
fprintf(stderr, "%s\n", mysql_error(db_conn));
}
strcpy(query, "\0");
strcat(query,"select * from user_info where user_id='");
strcat(query,login_id);
strcat(query,"'");
mysql_query(db_conn, query);
db_res = mysql_store_result(db_conn);
row = mysql_fetch_row(db_res);
if (row!=0) {
//send(sock,"T",sizeof("T"),0);
printf("\nT");
}
//freeing the result variable so it can be used further
mysql_free_result(db_res);
//release lock
sem_post(&sem);
break;
}//switch case
/*send(sock, "\nPlease enter your choice \n 1- File Download \n 2-File Upload\n 3-Rating\n", sizeof("\nPlease enter your choice \n 1- File Download \n 2-File Upload\n 3-Rating\n"), 0);*/
int nu=1;
do{
bzero(msg_serv_rec,sizeof(msg_serv_rec));
if(recv(sock, msg_serv_rec,sizeof(msg_serv_rec), 0)>0)
{
choice = msg_serv_rec ? *msg_serv_rec : '0';
printf("\n choice = %c\n", choice);
strcpy(query, "\0");
//printf("Client's choice is file Download\n" );
/*Sending File to the client line by line
checking the database connection*/
if(choice == '1'){
/*if(mysql_query(db_conn, "SELECT name FROM file_info")==0)
{
db_res = mysql_store_result(db_conn);
num_fields = mysql_num_fields(db_res);
if(num_fields>0)
{
while ((row = mysql_fetch_row(db_res)))
{
for(int i = 0; i < num_fields; i++)
{
char *fname1=row[i] ? row[i] : "NULL";
strcat(name,fname1);
strcat(name, "\n");
//send(sock,name,sizeof(name),0);
//printf("\n%s",name);
}
}
//sending list of all files to client
send(sock,name,sizeof(name),0);*/
/*emptying the name!!
strcpy(name, "");*/
//freeing the result variable so it can be used further
/*mysql_free_result(db_res);
sem_post(&sem);*/
bzero(msg_serv_rec,sizeof(msg_serv_rec));
if(recv(sock, msg_serv_rec,sizeof(msg_serv_rec), 0)>0)
{//which file recieved
printf("%s\n", msg_serv_rec );
// sem_wait(&sem);
f = fopen(strcat(fpath, msg_serv_rec),"r");
while(fgets(msg_serv_send, sizeof(msg_serv_send), f) !=NULL)
{
if((*msg_serv_send!=EOF || *msg_serv_send!='\n'))
{
send(sock, msg_serv_send, sizeof(msg_serv_send), 0);
//printf("\n%s", msg_serv_send);
}
else
break;
}
send(sock,"quit",sizeof("quit"),0);
fclose(f);
strcpy(fpath, "file_serv/");
//sem_post(&sem);
printf("\nFile sent to the client\n");
}
}
else if (choice == '0')
break;
strcpy(msg_serv_rec, "");
//stop = clock();
//time(NULL);
}
else
{
choice = '0';
}
}while ( choice != 'f' && choice != '0');
nu++;
/* unblocking the semaphores to allow other threads to access*/
//sem_post(&sem);
if(read_size == 0)
{
puts("\nClient disconnected\n");
fflush(stdout);
}
/*else if(read_size == -1)
{perror("recv failed");}
fclose(f);*/
close(sock);
pthread_exit(NULL);
}
int main()
{ int s,n,i, clilen;
int c;
int newsockfd;
int *new_sock;
start = clock();
//pthread_t handle;
struct sockaddr_in cli,serv;//socket address for client and server
MYSQL_ROW row;
MYSQL_RES *db_res;
//initializing the semaphore
sem_init(&sem, 0, 1);
//synchronization in DB
sem_wait(&sem);
/*Database connectivity*/
db_conn = mysql_init(NULL);
/* Connect to database */
if (!mysql_real_connect(db_conn, db_server, db_user, db_password, database, 0, NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(db_conn));
exit(1);
}
/* send SQL query */
if (mysql_query(db_conn, "show tables")) {
fprintf(stderr, "%s\n", mysql_error(db_conn));
exit(1);
}
db_res = mysql_use_result(db_conn);
/* output table name */
printf("MySQL Tables in mysql database:\n");
while ((row = mysql_fetch_row(db_res)) != NULL)
printf("%s \n", row[0]);
//freeing the result variable so it can be used further
mysql_free_result(db_res);
sem_post(&sem);
//Server socket
s=socket(AF_INET,SOCK_STREAM,0);
bzero((char*)&serv,sizeof(serv));
serv.sin_family=AF_INET;
serv.sin_port=htons(PORT);
serv.sin_addr.s_addr=inet_addr( SERV_ADDR);//"10.15.36.112");
/*printf("\nServer is waiting for client to respond");
i=0*/
//accept the incomming connections from client
bind(s,(struct sockaddr *)&serv,sizeof(serv));
printf("\nAddress bind successful");
listen(s,3000);//4 is the limit of the number of outstanding connections
n=sizeof(cli);
/*
i=0;
//accept the incomming connections from client
while( (c = accept(s, (struct sockaddr *)&cli, (socklen_t*)&n))) //&& (stop-start)<300 )
{ puts("Connection accepted\n");
pthread_t t;
printf("sock =%d\n", c);
if( pthread_create( &t , NULL , connect_client , (void*) c) < 0)
{
perror("could not create thread");
return 1;
}
i++;
/*Now detach the thread ,When a detached thread terminates, its resources are
automatically released back to the system without the need for
another thread to join with the terminated thread.*/
/* if ( ! pthread_detach(t) )
printf("Thread detached successfully !!!\n");
puts("Handler assigned");
stop = clock();
}*/
clilen=sizeof(cli);
while(newsockfd = accept(s, (struct sockaddr *) &cli, &clilen))
{
if(newsockfd < 0)
error("ERROR on accept");
else{
pthread_t handle;
new_sock = malloc(1);
*new_sock = newsockfd;
if(pthread_create(&handle, NULL,connect_client ,(void *)new_sock)<0)
error("Error creating thread");
else
printf("Thread fd: %d\n",newsockfd);
if ( ! pthread_detach(handle) )
printf("Thread detached successfully !!!\n");
}
}
/* close database connection */
mysql_free_result(db_res);
mysql_close(db_conn);
close(s);
/*destroying the mutex */
sem_destroy(&sem);
return 0;
}

multiprocess communications using message queue

I'm trying to implement a program similar to this example:
the program passes an integer among 4 processes and each process decrements the integer
each process have its own mailbox
Each process check its mailbox for variable "counter" and if it was found it will decrements it
Then it send the counter variable to the next process
but there is a bug in the program and I cant find it.
note that this an assignment and Im just looking for tips that helps me find the bug.
typedef struct {
int counter;
char data[256];
int id; //id of the process that previously decremented the counter
} msg;
int main(int arqc, char *argv[]){
int key=9;
int id=0;
pid_t pid;
int num=5;
int i, k;
int arr[5];
//create 5 forks
if (arqc != 2){
num=5;
}else{
int ret = sscanf(argv[1], "%d", &num);
if (ret != 1)return 0;
}
for(i=0 ; i<num ; i++){
if ((pid = fork()) == -1) {
fprintf(stderr, "can't fork, error %d\n", errno);
exit(EXIT_FAILURE);
}
if (pid == 0) {
id=i;
}
else {
break;
}
}
//process 1 to n comes here
msg m;
int boxid = msgget(id, 0600 | IPC_CREAT);
arr[id]=boxid;
int firstRun=1;
//initiate the first move
if((id==0)&&(firstRun==1)){
m.counter = INIT_COUNTER;
//send msg to next process
msgsnd(arr[id], &m, sizeof(msg), 0); //send msg to own inbox
firstRun=0;
}
while(1){
//check inbox of current process
int rec = msgrcv(arr[id], &m, sizeof(msg), 0, 0);
printf("Im %d, counter is %d, rec is %d\n",id, m.counter, rec);
int index;
if(id==num){
index=0;
}else{
index=id+1;
}
//send message to the next inbox
int sent = msgsnd(arr[index], &m, sizeof(m), 0);
printf( "Error opening file: %s\n", strerror( errno ) );
sleep(1);
}
}
Your initial msgsnd is failing with an invalid argument and everything get munged from there on.
SysV message queues require a message type field as the first field in a message so you need to do something like this.
typedef struct
{
long int mtype;
int counter;
char data[256];
int id; //id of the process that previously decremented the counter
} msg;
You also have to set the message to something and set the correct length before you send it.
//initiate the first move
if ((id == 0) && (firstRun == 1))
{
m.mtype = 100;
m.counter = INIT_COUNTER;
strncpy(m.data, "some kind of message is nice", sizeof(m.data));
m.id = id;
size_t msgsize = sizeof(msg) - sizeof(long int);
//send msg to next process
int sent = msgsnd(arr[id], &m, msgsize, 0); //send msg to own inbox
if (sent == -1)
{
perror("msgsend");
exit(1);
}
firstRun = 0;
}
You run into problems beyond this (e.g. set the correct size on the msgrcvs) but this should get you over the initial hump.
First of all, it is unreasonable to expect the SO crowd to just solve the (homework?) problem for you without any effort on your side. It is unclear what the problem is, how the program behaves currently, and what steps were made to debug it.
Rants aside, I'd recommend cutting out all the steps leaving only two participants and getting it to work in that simple configuration. Once it works, add another one, make sure it still works and so on.

Resources