This is my code with corrections. Now the code is compiling without any errors. The insertion part is doing good but there is a problem with display part. It is displaying only one person details where it has to display all the data. I think the problem is with read() and write(), but i couldn't correct it. Can anyone please help me. I have also included the code for checking the return value for socket, bind, connect, fread, fwrite. Can anyone please check if there is any wrong in read() and write() and how to make it to display all the data. I am highlighting the insert and display part in server.c and client.c to make it easy.
Code:
Server.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<unistd.h>
#include<errno.h>
#define FIRST_NAME_LENGTH 25
#define LAST_NAME_LENGTH 30
#define ADDRESS_LENGTH 25
#define NUMBER_LENGTH 15
typedef struct
{
int select;
char lastname[LAST_NAME_LENGTH];
char firstname[FIRST_NAME_LENGTH ];
char address[ADDRESS_LENGTH];
char phonenumber[NUMBER_LENGTH];
}addressbook;
typedef struct
{
char lastname[LAST_NAME_LENGTH];
char firstname[FIRST_NAME_LENGTH ];
}book;
book b= {0,0};
addressbook a={0,0};
FILE *fp;
char *filename = "addressbook.dat";
int main (int argc, char* const argv[])
{
int ret;
char answer = 'n';
const char* const socket_name ="/tmp/socket";
int socket_fd;
struct sockaddr_un name;
/* Create the socket. */
socket_fd = socket (PF_LOCAL, SOCK_STREAM, 0);
if (socket_fd < 0){
perror("socket");
exit (EXIT_FAILURE);
}
/* Indicate that this is a server. */
name.sun_family = AF_LOCAL;
strcpy (name.sun_path, socket_name);
if(bind (socket_fd, (struct sockaddr*)&name, SUN_LEN (&name)) == -1){
perror("bind");
exit (EXIT_FAILURE);
}
/* Listen for connections. */
listen (socket_fd, 5);
struct sockaddr_un client_name;
socklen_t client_name_len;
int client_socket_fd;
/* Accept a connection. */
client_socket_fd = accept (socket_fd, (struct sockaddr*)&client_name, &client_name_len);
do{
ret = read (client_socket_fd, &a, sizeof(addressbook));
printf("read return value:%d\n", ret);
if(ret < 0) {
perror("read");
exit (EXIT_FAILURE);
}
if(a.select == 1){
/* to insert data*/
if((fp = fopen(filename,"a+")) == NULL){
printf("Error opening %s for writing. Program terminated.\n", filename);
abort();
}
fwrite(&a, sizeof(addressbook), 1, fp); /* Write to the file */
fclose(fp); /* close file */
printf("New record added\n");
}else if (a.select == 2){
/* to display data*/
if((fp = fopen(filename, "r")) == NULL){
printf("Error opening %s for reading. Program terminated.", filename);
abort();
}
for(;;)
{
fread(&a, sizeof(addressbook), 1, fp); /*read from the file */
if(feof(fp)) /* If we read EOF */
break; /* done */
write (client_socket_fd, &a, sizeof(addressbook));
}
fclose(fp);
}else if (a.select == 3){
/*to delete data*/
FILE *newfp = NULL;
char *newfilename = NULL;
strcpy(b.lastname, a.lastname);
strcpy(b.firstname, a.firstname);
if((fp = fopen(filename, "r")) == NULL){
printf("Error opening %s for reading. Program terminated.", filename);
abort();
}
newfilename = tmpnam(NULL); // create temporary file name
if((newfp = fopen(newfilename, "w")) == NULL){
printf("Error opening %s for writing. Program terminated.", newfilename);
fclose(fp);
abort();
}
for(;;){
fread(&a, sizeof(addressbook), 1, fp); /* read the original file */
if(feof(fp)) /*If we read EOF */
break; /* done */
if((strcmp(b.firstname, a.firstname)==0) && (strcmp(b.lastname, a.lastname)==0)){
printf("record found\n");
printf("Do you really want to delete it(y or n)?");
scanf("%c", &answer);
if(tolower(answer) == 'y') /*if it's to be deleted*/
continue; /*skip copying*/
}
fwrite(&a, sizeof(addressbook), 1, newfp); /*copy current record*/
}
fclose(fp);
fclose(newfp);
if((newfp = fopen(newfilename, "r")) == NULL){ /* Open temporary file to read it */
printf("Error opening %s for reading. Program terminated.", newfilename);
abort();
}
if((fp = fopen(filename, "w"))==NULL){ /* Open original file to write it */
printf("Error opening %s for writing. Program terminated.", filename);
abort();
}
/* Copy contents of new temporary file back to old file */
/* This overwrites the original contents because the mode is "w" */
for(;;) {
fread(&a, sizeof(addressbook), 1, newfp); /* Read temporary file */
if(feof(newfp)) /* If we read EOF */
break; /* done */
fwrite(&a, sizeof(addressbook), 1, fp); /* Write record to original file */
write (client_socket_fd, &a, sizeof(addressbook));
}
fclose(fp); /* Close the original file */
fclose(newfp); /* Close the temporary file */
remove(newfilename); /* Delete the temporary file */
printf("Delete complete.");
}else if(a.select == 4){
/*to modify data*/
}else{
printf("wrong selection\n");
}
if((a.select > 4) || (a.select < 1))
break;
}while(1);
/* Close our end of the connection. */
close (client_socket_fd);
/* Remove the socket file.*/
close (socket_fd);
unlink (socket_name);
return 0;
}
Code:
Client.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#define FIRST_NAME_LENGTH 25
#define LAST_NAME_LENGTH 30
#define ADDRESS_LENGTH 25
#define NUMBER_LENGTH 15
typedef struct
{
int select;
char lastname[LAST_NAME_LENGTH];
char firstname[FIRST_NAME_LENGTH];
char address[ADDRESS_LENGTH];
char phonenumber[NUMBER_LENGTH];
}addressbook;
addressbook a={0,0};
int main (int argc, char* const argv[])
{
const char* const socket_name = "/tmp/socket";
const char* const message;
int socket_fd;
int ret;
struct sockaddr_un name;
/* Create the socket. */
if((socket_fd = socket (PF_LOCAL, SOCK_STREAM, 0)) == -1){
perror("socket");
exit (EXIT_FAILURE);
}
/* Store the server’s name in the socket address. */
name.sun_family = AF_LOCAL;
strcpy (name.sun_path, socket_name);
/* Connect the socket. */
if(connect (socket_fd, (struct sockaddr*)&name, SUN_LEN (&name)) == -1){
perror("connect");
exit (EXIT_FAILURE);
}
do {
printf("Address book: \n Press\n 1: Insert \n 2: Display \n3: Delete \n 4: Modify\n Enter:");
scanf("%d", &a.select);
if(a.select == 1){
/* Write the text on the command line to the socket.*/
printf("enter details\n");
printf("enter lastname of person :\n");
scanf("%s", a.lastname);
printf("enter firstname of person :\n");
scanf("%s", a.firstname);
printf("enter address of person :\n");
scanf("%s", a.address);
printf("enter phone number of person :\n");
scanf("%s", a.phonenumber);
write (socket_fd, &a, sizeof(addressbook));
sleep (1);
}else if(a.select == 2){
write (socket_fd, &a, sizeof(addressbook));
sleep (1);
read (socket_fd, &a, sizeof(addressbook));
printf(" %s, %s, %s, %s\n", a.lastname, a.firstname, a.address, a.phonenumber);
}else if(a.select == 3){
printf("enter lastname of person to delete:\n");
scanf("%s", a.lastname);
printf("enter firstname of person to delete :\n");
scanf("%s", a.firstname);
write (socket_fd, &a, sizeof(addressbook));
sleep (1);
}else if(a.select == 4){
printf("enter lastname of person to modify:\n");
scanf("%s", a.lastname);
printf("enter firstname of person to modify :\n");
scanf("%s", a.firstname);
write (socket_fd, &a, sizeof(addressbook));
sleep (1);
}else{
printf("wrong selection\n");
}
if((a.select > 4) || (a.select < 1))
break;
}while(1);
/*close the socket */
close (socket_fd);
return 0;
}
Please suggest me if there is any wrong in my code. I am new to Linux programming, so I am trying to use sockets for reading and writing data from one process to another. Thank you.