0

I am working on a project where I need to convert a string to binary format and implement cyclic redundancy check (crc) on the binary data. The data need to transfer though a client-server communication. I need to provide two files city.txt and country.txt and the data of those two files need to convert first in binary and implemented crc on it and send those files to server and server remove the crc and change it back to string again and send it to client. All this those function work well for the 1st file that I send though the network (city.txt) but for the second file it did not work.

The client side code is

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#define SIZE 2024
// Function to run the CRC service and generate the CRC file
void CRC(const char *inputFile, const char *outputFile) {
 pid_t pid = fork();
 if (pid < 0) {
 perror("[-]Error in fork");
 exit(1);
 } else if (pid == 0) {
 FILE *fp = fopen(outputFile, "w");
 if (!fp) {
 perror("[-]Error in opening output file");
 exit(1);
 }
 dup2(fileno(fp), STDOUT_FILENO);
 fclose(fp);
 execlp("./crc", "./crc", inputFile, NULL);
 perror("[-]Error in execlp for CRC service");
 exit(1);
 } else {
 wait(NULL);
 }
}
void write_file(int sockfd, const char *filename) {
 
}
 
void send_file(int sockfd, const char *filename) {
 
}
int main() {
 char *ip = "127.0.0.1";
 int port = 8080;
 int sockfd, e;
 struct sockaddr_in server_addr;
 FILE *fp;
 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0) {
 perror("[-]Error in socket");
 exit(1);
 }
 printf("[+]Server socket created successfully.\n");
 
 e = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
 if (e == -1) {
 perror("[-]Error in connecting to server");
 exit(1);
 }
 printf("[+]Connected to Server.\n");
 
 CRC("city.txt", "ccity.txt");
 sleep(1);
 
 
 // Send citycrc.txt to the server
 fp = fopen("citycrc.txt", "r");
 if (fp == NULL) {
 perror("[-]Error in reading citycrc.txt");
 exit(1);
 }
 printf("[+]Sending citycrc.txt to the server\n");
 send_file(sockfd, "citycrc.txt");
 fclose(fp);
 printf("[+]citycrc.txt sent successfully.\n");
 sleep(1);
 // Send countrycrc.txt to the server
 fp = fopen("countrycrc.txt", "r");
 if (fp == NULL) {
 perror("[-]Error in reading countrycrc.txt");
 exit(1);
 }
 printf("[+]Sending countrycrc.txt to the server\n");
 send_file(sockfd, "countrycrc.txt");
 fclose(fp);
 printf("[+]countrycrc.txt sent successfully.\n");
 sleep(1);
 // Receive crcascii.txt from the server
 
 write_file(sockfd, "crcasciicity.txt");
 printf("[+]crcasciicity.txt received successfully.\n");
 sleep(1);
 printf("[+]Receiving crcasciicountry.txt from the server\n");
 write_file(sockfd, "crcasciicountry.txt");
 printf("[+]crcasciicountry.txt received successfully.\n");
 // Close the connection
 close(sockfd);
 printf("[+]Connection closed.\n");
 return 0;
}

Server side code :

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define SIZE 5024
// Function to receive a file from the client
void write_file(int sockfd, const char *filename) {
 
}
void send_file(int sockfd, const char *filename) {
 
}
// Function to extract, flip MSB, convert to ASCII, and save to ASCII file
void extract_flip_and_save_ascii(const char *inputFile, const char *outputFile) {
 
}
int main() {
 char *ip = "127.0.0.1";
 
 int sockfd, new_sock;
 struct sockaddr_in server_addr, new_addr;
 socklen_t addr_size;
 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0) {
 perror("[-]Error in socket");
 exit(1);
 }
 printf("[+]Server socket created successfully.\n");
 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(port);
 server_addr.sin_addr.s_addr = inet_addr(ip);
 if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
 perror("[-]Error in bind");
 exit(1);
 }
 printf("[+]Binding successful.\n");
 if (listen(sockfd, 10) == 0) {
 printf("[+]Listening...\n");
 } else {
 perror("[-]Error in listening");
 exit(1);
 }
 addr_size = sizeof(new_addr);
 new_sock = accept(sockfd, (struct sockaddr*)&new_addr, &addr_size);
 if (new_sock < 0) {
 perror("[-]Error in accepting connection");
 exit(1);
 }
 printf("[+]Connection accepted.\n");
 // Receive citycrc.txt from the client
 write_file(new_sock, "citycrc.txt");
 printf("[+]citycrc.txt received successfully.\n");
 // Receive countrycrc.txt from the client
 write_file(new_sock, "countrycrc.txt");
 printf("[+]countrycrc.txt received successfully.\n");
 // Generate crcasciicity.txt from citycrc.txt
 extract_flip_and_save_ascii("citycrc.txt", "crcasciicity.txt");
 printf("[+]crcasciicity.txt generated successfully.\n");
 // Send crcasciicity.txt to the client
 printf("[+]Sending crcasciicity.txt to the client.\n");
 send_file(new_sock, "crcasciicity.txt");
 printf("[+]crcasciicity.txt sent successfully.\n");
 sleep(1);
 // Generate crcasciicountry.txt from countrycrc.txt
 extract_flip_and_save_ascii("countrycrc.txt", "crcasciicountry.txt");
 printf("[+]crcasciicountry.txt generated successfully.\n");
 
 
 send_file(new_sock, "crcasciicountry.txt");
 printf("[+]crcasciicountry.txt sent successfully.\n");
 // Close the connection
 close(new_sock);
 close(sockfd);
 printf("[+]Connection closed.\n");
 return 0;
}

city.txt has data like Clinton, Greenvile,...

county.txt has data like Canada, Brazil...

citycrc.txt holds binary representation of city.txt file like "10" format.

countrycrc.txt holds binary representation of country.txt file like "10" format.

cityasciicrc.txt takes citycrc.txt as input and do the extract_flip_save_ascii() operation on it and return back Clinton, Greenvile. countryasciicrc.txt takes countrycrc.txt as input and do the extract_flip_save_ascii() operation on it and return back Canada, Brazil.

When I run the server's executable I received the output

[+]Server socket created successfully.
[+]Binding successful.
[+]Listening...

Then I run client's executable I received the output

[+]Server socket created successfully.
[+]Connected to Server.
[+]Generating CRC for city.txt
[+]Generating CRC for country.txt
[+]Sending citycrc.txt to the server
[+]citycrc.txt sent successfully.
[+]Sending countrycrc.txt to the server
[+]countrycrc.txt sent successfully.
[+]Receiving crcasciicity.txt from the server
[+]crcasciicity.txt received successfully.
[+]Receiving crcasciicountry.txt from the server
[-]Error in receiving file size: Success
[+]crcasciicountry.txt received successfully.
[+]Connection closed.

Then if I checked the server's output I found some added output

[+]Connection accepted.
[+]citycrc.txt received successfully.
[+]countrycrc.txt received successfully.
[+]crcasciicity.txt generated successfully.
[+]Sending crcasciicity.txt to the client.
[+]crcasciicity.txt sent successfully.
[-]Error: Not enough bits to extract data part.
[+]crcasciicountry.txt generated successfully.
[+]Sending crcasciicountry.txt to the client.
[-]Error in opening file: No such file or directory

Now I think in the server side getting the output "[-]Error: Not enough bits to extract data part.", is for country.txt. Since I found countrycrc.txt was empty and crcasciicountry.txt was empty,

I did not understand when the codes work well for city.txt, the first file of client-server communication, why it was not working for country.txt?

I am using Ubuntu 20.04, one pc and two terminals to implement client server communication.

Thank you. Any help will be appreciated.

asked Oct 29, 2024 at 17:18
2
  • This crcservice_v2 program, what does it do? What is the format of its output file? Is it a text file? Commented Oct 29, 2024 at 17:24
  • Have you looked on the server side to see what was actually received (and written to files) on that side? Does the console output on that side tell you anything useful? Commented Oct 29, 2024 at 17:50

1 Answer 1

3

You seem to have the wrong idea about the behavior of read() and recv(). Your code is assuming that it will observe a zero-byte read at the end of the data for each individual file transferred, but this is not the case, and no amount of delay between the files will change that. TCP is a stream protocol. It has no built-in sense of messages or other subdivisions, unless you consider individual bytes to be such. End of file on a socket is not about the data transmitted -- it is about whether the socket is still open, such that additional data might still be transmitted.

To be able to recognize the two files as separate units, you need to layer some kind of application protocol on top of the raw byte stream. That could be as simple as putting a byte count in front of each file's data, such that the receiver knows it has reached the end of that file by having read exactly that many (additional) bytes. More complex schemes are possible too, of course.

answered Oct 29, 2024 at 17:58
Sign up to request clarification or add additional context in comments.

6 Comments

I updated the server write() and client send(). Now the client executable did not stuck. But country.txt, the second file generated empty coutrycrc.txt and coutrycrcascii.txt. I did not understand my codes work for the 1st file but the same code fail for the second file. Why?
@Encipher, at minimum, you (still) have the same issue with the server sending results back to the client that you did for the client sending inputs to the server.
Ok, then how the first file (city.txt) work well and executed all the operations?
@Encipher, I would be inclined to guess that city.txt did not work as well as you think. Most likely, the client received back not only the city data but also the country data into that file, though some of it may still be buffered in memory if you check before the client terminates normally, and may be lost altogether if the client is terminated abruptly instead of normally.
I changed the code blocks and my question after getting your suggestion. Now the only operations is not work on the second file that is country.txt.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.