You are not logged in.
Pages: 1
Hello everybody,
I'm trying to write a c code with sockets to communicate a server and a client (or father and child, as you prefer) but I'm really noob at this. I know there are lots of problems in my code, but right now I keep getting a "segmentation fault" error. I know that the elements doesn't point each other but it's too late in my country and this all seems like a foreign language to me.
I would really appreciate any help that you could offer me.
That's all, thanks in advance.
SERVER.c CODE-------------------------------------------------------------------------------------------------------------------------------------------------------------
//#include <sys/un.h> //per utilitzar sockaddr_un
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> //per utilitzar sockaddr
#include <unistd.h>
#define FEMISSOR "multi.socket" // per enviar dades a l'emissor ????????
int main(int argc, char *argv[]){ //si es volen utilitzar paràmetres
int s; //el socket
int n;
int i, j;
char c, num_fill[6];
struct sockaddr s_struct; //l'estructura del socket
unsigned int v; //per guardar el tamany de s_struct
char msg[50]; //buffer dels missatges
int a11, a12, a21, a22, b11, b12, b21, b22;
int a, b, x, d; //Las variables que guardan los valores de las matrices.
//Introduccion de los valores de la Matriz 1
printf ("Introduce la primera matriz en orden a11 a12 a21 a22:\n");
scanf ("%d %d %d %d", &a11, &a12, &a21, &a22);
//Introduccion de los valores de la Matriz 2
printf ("Introduce la segunda matriz en orden b11 b12 b21 b22:\n");
scanf ("%d %d %d %d", &b11, &b12, &b21, &b22);
printf ("Los valores de las matrices son: %d %d %d %d; %d %d %d %d\n", a11, a12, a21, a22, b11, b12, b21, b22);
//Realizar la introducción de las matrices
for (i=0;i<4;i++){
printf ("Entra en el for de FORKS\n");
sprintf(num_fill, "Fill%d", i);
if (fork()==0){ //es pot crear un procés fill i executar ./receptor
printf ("Entra en el fork %d\n", i);
execl("./fill", "fill", num_fill, NULL);
exit(0);}
printf ("Imprimeix nom: %s\n", num_fill);
}
printf("Emissor. Esperant uns segons a que el receptor hagi creat el seu socket\n");
sleep(1); // ho ha de fer el primer que s'executa per esperar l'altre, de 1s a Xs
if ((s=socket(AF_UNIX, SOCK_DGRAM,0)) <0){ //crea el socket
perror ("Emissor. Error socket:");
exit(1);
}
s_struct.sa_family=AF_UNIX;
strcpy(s_struct.sa_data, FEMISSOR); //Emisor
if (bind (s, &s_struct, sizeof(s_struct))<0){ //associa un nom de fitxer al socket
perror ("Emissor. Error associant:"); //qui reb és qui ha de fer el bind
close(s);
exit(2);
}
for (i=0; i<4; i++){
switch (i) {
case 0:
a=a11 ; b=a12 ; x=b11 ; d=b21;
break;
case 1:
a=a11 ; b=a12 ; x=b12 ; d=b22;
break;
case 2:
a=a21 ; b=a22 ; x=b11 ; d=b21;
break;
case 3:
a=a21 ; b=a22 ; x=b12 ; d=b22;
break;
}
s_struct.sa_family=AF_UNIX;
sprintf (num_fill, "Fill%d", i);
strcpy(s_struct.sa_data, num_fill); //envia al fitxer socket del receptor
v= sizeof(s_struct);
sprintf(msg, "%d %d %d %d", a, b, x, d);
printf("Multi. Enviant dades a %s", s_struct.sa_data );
if((n=sendto(s, msg, strlen(msg)+1, 0, &s_struct, sizeof(s_struct)))<0) {
perror ("Multi. Error enviant:\n");
unlink(num_fill); //Al receptor: FRECEPTOR
close (s);
exit(3);
}
printf("Emissor. %d dades enviades: %s\n", n, msg);
}
// for para recibir los datos de los hijos
for (i=0; i<4; i++){
s_struct.sa_family=AF_UNIX;
strcpy(s_struct.sa_data, FEMISSOR); //envia al fitxer socket del receptor
if((n=(recvfrom(s, &msg, sizeof(msg), 0, &s_struct, &v)))<0) {
perror ("Multi. Error rebent:");
unlink(FEMISSOR); //Al receptor: FRECEPTOR
close (s);
exit(3); //Al receptor: n=(recvfrom(s, &msg, sizeof(msg), 0, &s_struct, &v))
}
if ( strncmp(s_struct.sa_data,"Fill0",5)==0){
sscanf(msg,"%d", &a);}
if ( strncmp(s_struct.sa_data,"Fill1",5)==0){
sscanf(msg,"%d", &b);}
if ( strncmp(s_struct.sa_data,"Fill2",5)==0){
sscanf(msg,"%d", &x);}
if ( strncmp(s_struct.sa_data,"Fill3",5)==0){
sscanf(msg,"%d", &d);}
}
printf("Datos recibidos de %s\n", s_struct.sa_data);
printf("Resultado de la multiplicacion:\n");
printf("Matriu 1: %d %d\n %10d %d\n", a11, a12, a21, a22);
printf("Matriu 2: %d %d\n %10d %d\n", b11, b12, b21, b22);
printf("Matriu R: %d %d\n %10d %d\n\n", a, b, x, d);
printf("Emissor. Prem una tecla per acabar i eliminar el socket\n");
// for para imprimir las matrices.
scanf("%c",&c);
unlink(FEMISSOR); //es tanca el fitxer que s'ha obert al bind
close(s);
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------
CLIENT.c CODE
//#include <sys/un.h> //per utilitzar sockaddr_un
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h> //per utilitzar sockaddr
#include <unistd.h>
//s'utilitzen dos fitxers, un pel socket de cada procés. Cada procés fa el bind del seu
//Al sendto y al recvfrom es posa al camp sa_data el fitxer a qui es fa la petició.
#define FEMISSOR "multi.socket" // per enviar dades a l'emissor
#define Fill0 "f0.socket" // per enviar dades al receptor (si és bidireccional) <---- i think those lines are not supposed to exist XD
#define Fill1 "f1.socket"
#define Fill2 "f2.socket"
#define Fill3 "f3.socket"
int main(int argc, char *argv[1]){ //si es volen utilitzar paràmetres
int s; //el socket
int n;
char c, num_fill[6];
struct sockaddr s_struct; //l'estructura del socket
unsigned int v; //per guardar el tamany de s_struct
char msg[50]; //buffer dels missatges
int a1, a2, b1, b2; //Las variables para ingresar los numeros.
int resultado;
strcpy (num_fill, argv[1]);
printf ("Creat %s\n", num_fill);
if ((s=socket(AF_UNIX, SOCK_DGRAM,0))<0){//crea el socket
perror ("Fill. Error socket:");
exit(1);
}
s_struct.sa_family=AF_UNIX;
strcpy(s_struct.sa_data, num_fill); //El receptor utilitzarà el nom FRECEPTOR
if (bind (s, &s_struct, sizeof(s_struct))<0){ //associa un nom de fitxer al socket
perror ("Fill. Error associant:"); //qui reb és qui ha de fer el bind
close(s);
exit(2);
}
s_struct.sa_family=AF_UNIX;
strcpy(s_struct.sa_data, num_fill);
//Recibe los datos del receptor
if((n=(recvfrom(s, &msg, sizeof(msg), 0, &s_struct, &v)))<0) {
perror ("Receptor. Error enviant:");
unlink(num_fill); //Al receptor: FRECEPTOR
close (s);
exit(3); //Al receptor: n=(recvfrom(s, &msg, sizeof(msg), 0, &s_struct, &v))
}
printf("Datos recibidos en %s\n", num_fill);
sscanf(msg,"%d %d %d %d",&a1,&a2,&b1,&b2);
resultado = (a1*b1)+(a2*b2);
printf ("El resultado de %s es: %d\n", num_fill, (int) resultado);
s_struct.sa_family=AF_UNIX;
strcpy(s_struct.sa_data, num_fill); //envia al fitxer socket del receptor
v= sizeof(s_struct);
sprintf(msg, "%d", resultado);
printf("Fill. Enviant resultat a %s\n", s_struct.sa_data );
if((n=sendto(s, msg, strlen(msg)+1, 0, &s_struct, sizeof(s_struct)))<0) {
perror ("Emissor. Error enviant:");
unlink(num_fill); //Al receptor: FRECEPTOR
close (s);
exit(3);
}
printf("%s. %d dades enviades: %s\n", num_fill, n, msg);
unlink(num_fill); //es tanca el fitxer que s'ha obert al bind
close(s);
}
-----------------------------------------------------------------------------------------------------------------------------------------------------
PS: The code is supposed to be multipliying two 2x2 arrays. The father creates a socket to communicate with the child. There must be 5 processes: The father creates 4 child processes that multiply one row for one column to get the 4 resultant integers. Child processes will be paralel-executed.
Main process creates a socket to communicate with childs that will then be created, codified into an external program. It also passes an arguments that is the # of the child. Childs create their own socket. Each one will use a different file for the linkage (fitxerf1, fitxerf2....fitxerf4). The father waits 1 second for its child to create the sockets.
Once the link has been created, the father passes each child 4 int values using each file. Each child will return to the father's communication file the solution of each multiplication.
Eventually, the father shows what it's receiving from each child and the three arrays (the first ones and the result).
For one thing, you should really be using "struct sockaddr_un" for AF_UNIX sockets, not plain old "struct sockaddr"... However, that's probably not your real problem here...
I'm guessing the main problem is failure to intialize the value of "v" that you pass to recvfrom()... That needs to be set to the size of your sockaddr struct prior to every call, and on return it will be filled with the actual size of the peer's address... Leaving it unitialized just gives it some garbage value from your stack contents...
Also, unless I'm missing something, it looks to me like the clients aren't sending the answer back to the server/parent, but rather are sending it to their own address! The recvfrom() already filled in the server/parent's address into your "s_struct", so you don't need to bother filling it in again after that, but can just use it as-is in the following sendto()... (You should also use the value of "v" filled in by the recvfrom() as the passed length, as well...)
Offline
Thanks a lot RobSeace, I'm trying to get it done right now....let's see if I manage to solve this...
thanks again for your time.
Pages: 1