I have a structure of account (like a bank account) and i want to send the information of account to the client when i write "state" on starting of the app: ./client state
then the server must to send the information of client, however i have a problem to send the structure with fwrite function,
i have implemented this on my server.c
...
if(strcmp(buffer, "state") == 0) {
printf("sending the state of account...\n");
memcpy(buffer, &a1, sizeof(a1));
printf("%s\n", buffer);
size_t nb_write = fwrite(buffer, sizeof(char), sizeof(MAX_BUFF), client_array[0].file);
printf("number i write: %ld\n", nb_write);
if(fflush(client_array[0].file)){
syserr("error of fflush");
}
}
and on my client.c i have written this:
...
if(argc > 1){
printf("argv[1]: %s\n", argv[1]);
size_t nb_write = fwrite(argv[1], sizeof(*argv), strlen(argv[1]), fdc);
printf("number i write: %ld\n", nb_write);
if(fflush(fdc)){
syserr("fflush");
}
}
size_t nbread = fread(&buffer, strlen(buffer), sizeof(BUFF_SIZE), fdc); // reception of structure
printf("number i read: %ld\n", nbread);
printf("%s\n", buffer);
the app client is waiting with the fread()
the output of ./server
:
number i read: 4
state
sending the state of account...
account 1
number i write: 4
error of fflush: Illegal seek
And when i do CTRL-C to stop the server, the app client write something strange (the content of the buffer maybe) and the app is stopping also.
Socket creation successful
Connection successful !
argv[1]: state
number i write: 5
number i read: 0
��E-�
here the structure i want to send:
struct account{
char title[MAX_TITLE_LENGTH];
struct user list_user[MAX_LIST_SIZE];
// char description[140]; // for example hotel, market, travel
int32_t total;
};
struct account a1;
/* ACCOUNT */
strcpy(a1.title, "account 1");
a1.list_user[0] = u1;
a1.total = 0.0;
How can i fix it to send the structure correctly on the fd of client and read it on my client's buffer
CodePudding user response:
I see many mistakes in this code:
sizeof(MAX_BUFF)
in the server'sfwrite()
is wrong. You need to use either justMAX_BUFF
orsizeof(buffer)
instead.sizeof(*argv)
in the client'sfwrite()
is wrong.*argv
(akaargv[0]
) is achar*
, not achar
. You need to usesizeof(char)
ie1
instead.the client is not sending either the command's null terminator or the command's length to the server, so how do you expect the server to know when the end of the command is reached? There is no 1:1 relationship between writes and reads in TCP, so you have to account for the data's actual size one way or the other.
when the client calls
fread()
,&buffer
,strlen(buffer)
, andsizeof(BUFF_SIZE)
are all wrong. While&buffer
may work,strlen(buffer)
certainly will not, as thebuffer
hasn't been populated with a null-terminated string, so you need to usesizeof(char)
ie1
instead. Andsizeof(BUFF_SIZE)
needs to be either justBUFF_SIZE
orsizeof(buffer)
instead.printf("%s\n", buffer);
in both client and server is wrong, sincebuffer
is clearly not a null-terminated string.the client is expecting to receive the struct even if the client doesn't request the server to send it.
With that said, try something more like this:
...
char *cmd = NULL;
size_t size;
ssize_t len;
if ((len = getdelim(&cmd, &size, '\0', client_array[0].file)) < 0) {
syserr("error of getdelim");
fclose(client_array[0].file);
}
else if (strcmp(cmd, "state") == 0) {
printf("sending the state of account...\n");
uint32_t size = htonl(sizeof(a1));
size_t nb_write = fwrite(&size, sizeof(size), 1, client_array[0].file);
if (nb_write == 1) {
nb_write = fwrite(&a1, sizeof(a1), 1, client_array[0].file);
}
if (nb_write < 1) {
syserr("error of fwrite");
fclose(client_array[0].file);
}
else {
printf("number i write: %ld\n", sizeof(size) sizeof(a1));
if (fflush(client_array[0].file) != 0) {
syserr("error of fflush");
}
}
}
free(cmd);
...
if (argc > 1) {
printf("argv[1]: %s\n", argv[1]);
if (fwrite(argv[1], strlen(argv[1]) 1, 1, fdc) < 1) {
syserr("error of fwrite");
fclose(fdc);
}
else if (fflush(fdc) != 0) {
syserr("fflush");
}
uint32_t size;
size_t nb_read = fread(&size, sizeof(size), 1, fdc);
if (nb_read == 1) {
size = ntohl(size);
nb_read = fread(buffer, size, 1, fdc);
}
if (nb_read < 1) {
syserr("error of fread");
fclose(fdc);
}
else {
printf("number i read: %ld\n", sizeof(size) size);
printf("%.*s\n", size, buffer);
}
}
CodePudding user response:
To read something send by the client i have this on my server.c
size_t nbread;
client_array[0].file = fdopen(client_array[0].fd, "w ");
nbread = fread(buffer, sizeof(char), 1, client_array[0].file);
if(nbread < 1){
syserr("fread");
return true;
}
printf("number i read: %ld\n", nbread);
printf("%s\n",buffer);
And I realized the reading have also a problem. If somebody can help me