Creating a file transfer application using UDP in C - c

I am trying to implement a server-client application in which the client sends the name of file to server. The server looks for the file and if the file exist it sends the file to the client back and this goes on . Here is the code i have written but the problem is that the server does not send the content of file back to client I had the same problem earlier ,then i re-wrote the code .
Here is the code :-
Server Side
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>
int main() {
char buff[20];
char content[200];
int sd, connfd, len, bytes_read;
struct sockaddr_in servaddr, cliaddr;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == -1) {
puts("socket not created in server");
return 1;
} else {
puts("socket created in server");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(7802);
if (bind(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
puts("Not binded");
return 1;
} else {
puts("Binded");
}
len = sizeof(cliaddr);
recvfrom(sd, buff, 1024, 0, (struct sockaddr *)&cliaddr, &len);
printf("%s\n", buff);
FILE *fp = fopen(buff, "r");
if (fp == NULL) {
printf("File does not exist \n");
return 1;
}
while (1) {
bytes_read = read(fp, content, sizeof(content));
if (bytes_read == 0)
break;
sendto(sd, content, sizeof(content), 0, (struct sockaddr*)&cliaddr, len);
bzero(content, 200);
}
strcpy(content, "end");
sendto(sd, content, sizeof(content), 0, (struct sockaddr*)&cliaddr, len);
return 0;
}
Client side:
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netinet/in.h>
#include <sys/types.h>
int main() {
int count = 0;
char buff[20], output[20];
char file_buffer[200];
int sockfd, connfd, len;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
puts("socket not created in client");
return 1;
} else {
puts("socket created in client");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; // ANY address or use specific address
servaddr.sin_port = htons(7802); // Port address
puts("Type your UDP client message");
scanf("%s", buff);
puts("enter the name of new file to be saved");
scanf("%s", output);
// send msg to server
sendto(sockfd, buff, strlen(buff) + 1, 0,
(struct sockaddr *)&servaddr, sizeof(struct sockaddr));
count++;
printf("%d\n", count);
FILE *fp = fopen(output, "a");
if (fp == NULL) {
puts("error in file handling");
return 1;
}
recvfrom(sockfd, file_buffer, sizeof(file_buffer), 0, NULL, NULL);
while (1) {
if (strcmp(file_buffer, "end") == 0)
break;
printf("%s", file_buffer);
write(fp, file_buffer, strlen(file_buffer));
bzero(file_buffer, 200);
recvfrom(sockfd, file_buffer, sizeof(file_buffer), 0, NULL, NULL);
}
puts("completed");
return 0;
}

Probably you should use the fread() function instead of read() on server side.
Functions fopen() and read() are parts of different interfaces:
Family read() -> open, close, read, write, ioctl (system calls)
Family fread() -> fopen, fclose, fread, fwrite, fcntl (standard library)
I can suppose that file descriptor given by fopen() is not exactly the same as read() expects.
The same on client side. You use the fopen() to open file and write() to write. Please use the fwrite()

Related

Client code is unable to read data from server [sockets]

My objective is to implement a simple data transfer from server to client. The problem is that the client is unable to read data from the server most of the time (it only works sometimes) even though the server says that the transfer was successful.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8080
void main() {
int sock = socket(AF_INET, SOCK_STREAM, 0), option = 1;
struct sockaddr_in address;
socklen_t addrlen = sizeof(address);
char buffer[1024] = {0};
char source_file[] = "<path>/something.txt";
char fname[] = "something.txt";
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
if(bind(sock, (struct sockaddr*) &address, sizeof(address)) == -1){
perror("Could not bind to address");
return;
}
if(listen(sock, 5) == -1) {
perror("Error while listening to connections");
return;
}
int new_socket = accept(sock, (struct sockaddr*) &address, &addrlen);
if(new_socket == -1){
perror("Error connecting to client");
exit(EXIT_FAILURE);
}
else printf("Connected to client\n");
// first send the filename
if(send(new_socket, fname, sizeof(fname), 0) == -1){
perror("Error while sending file");
return;
}
printf("Sending file %s\n\n", source_file);
FILE* f = fopen(source_file, "r");
// send the contents of the file
while(fgets(buffer, sizeof(buffer), f)){
printf("Sending %s", buffer);
if(send(new_socket, buffer, strlen(buffer), 0) == -1)
perror("Error while sending\n");
else printf("Successfully sent\n\n");
memset(buffer, 0, sizeof(buffer));
}
printf("File transfer complete\n");
fclose(f);
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
void main() {
int sock = socket(AF_INET, SOCK_STREAM, 0);
long val;
struct sockaddr_in address;
char buffer[1024] = {0};
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
if(inet_pton(AF_INET, "127.0.0.1", &address.sin_addr) == -1){
perror("Invalid IP value");
exit(EXIT_FAILURE);
}
if(connect(sock,(struct sockaddr*) &address, sizeof(address)) == -1){
perror("Connection Error");
exit(EXIT_FAILURE);
}
else printf("Connected to server\n");
// Get file name from server
if(read(sock, buffer, sizeof(buffer)) == -1){
perror("Could not read filename from server");
exit(EXIT_FAILURE);
}
printf("Receiving file %s\n", buffer);
FILE *f = fopen(buffer, "w");
// printf("%ld", read(sock, buffer, sizeof(buffer)));
while((val = read(sock, buffer, sizeof(buffer)))){
if (val == 0) break;
if (val == -1) {
perror("Error reading the content");
break;
}
printf("Read returned %ld\n", val);
printf("Received %s", buffer);
fputs(buffer, f);
memset(buffer, 0, sizeof(buffer));
}
printf("File transfer complete\n");
fclose(f);
}
Sample text file for data transfer
Hello there!
Nice to meet you.
This is a text file.
Bye Bye :)
Have a good day.
Execution from server side
$ cc ./server.c -o server
$ ./server
Connected to client
Sending file /home/username/Documents/something.txt
Sending Hello there!
Successfully sent
Sending Nice to meet you.
Successfully sent
Sending This is a text file.
Successfully sent
Sending Bye Bye :)
Successfully sent
Sending Have a good day.
Successfully sent
File transfer complete
This was the output I got from the server-side. This is weird because on client-side I didn't receive any message
$ cc ./client.c -o client
$ ./client
Connected to server
Receiving file something.txt
File transfer complete
The while loop in client side did not execute at all (because the data within buffer wasn't printed) and the read function did not return -1 otherwise a proper message would have been displayed.
This exact client code only works sometimes and other times it doesn't. What's the problem here?

Socket operation on non-socket C

I am getting this error when trying to make an application to connect and listen to a port for data.
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char * arg[]){
int conn_s = socket(AF_INET, SOCK_STREAM, 0); //Create the socket
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(1234);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int res = bind(conn_s, (struct sockaddr *) &servaddr, sizeof(servaddr));
if(res < 0){
printf("Error has occured\n");
}
FILE * stream = fdopen(conn_s, "w+"); //Create a stream for the socket
FILE * file = fopen("response2.txt", "w+"); //Create a file to store the output of the stream
char * line = NULL; //Where each line of the stream will be stored in
size_t len = 0; // The length of the line
ssize_t bytes; //The size of the line in bytes
int lis = listen(conn_s, SOMAXCONN);
fcntl(lis, F_SETFL, O_NONBLOCK);
while(1) {
conn_s = accept(lis, NULL, NULL);
if(conn_s < 0){
if((errno == EAGAIN) || (errno == EWOULDBLOCK))
continue;
perror("Failed to accept connection");
exit(EXIT_FAILURE);
}
long conn_s_flags = fcntl(conn_s, F_GETFL);
fcntl(conn_s, F_SETFL, conn_s_flags & ~O_NONBLOCK);
while((bytes = getline(&line, &len, stream)) != -1) {
printf("%s\n", line);
fwrite(line, sizeof(char), bytes, file);
}
close(conn_s);
}
free(line);
return 0;
}
I am trying to connect to port 1234, listen to it and accept it to recieve data, but the error keeps occuring.
Also I am trying to test using netcat, but get a different error whenever nc is running on the port I specified.
Thanks
int lis = listen(conn_s, SOMAXCONN);
fcntl(lis, F_SETFL, O_NONBLOCK);
while(1) {
conn_s = accept(lis, NULL, NULL);
listen() does not return a socket FD. It returns zero or -1. The second line is therefore erroneous, as is the following accept() call. It should be:
if (listen(conn_s, SOMAXCONN) == -1)
{
perror("listen");
return; // or whatever
}
fcntl(conn_s, F_SETFL, O_NONBLOCK);
while(1) {
int conn_c = accept(conn_s, NULL, NULL);
NB Don't lose conn_s by storing the result of accept() into it.

How can I solve the segmentation fault in socket programing? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a problem in linux coding.
When I send file name to server, I get the segmentation fault in server.
It may happen in read.
But, I can't find any idea to solve it.
Any suggestions?
Client Source code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUFMAX 256
void error_handling(const char *msg)
{
fputs(msg, stderr);
fputc('\n', stderr);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, h_err;
int file_len = 0;
int buf_size = 0;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[BUFMAX];
FILE *file;
char *file_name;
char *file_cont;
if (argc < 2)
error_handling("ERROR! No simulator provided\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error_handling("ERROR opening socket\n");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(5000);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error_handling("ERROR connecting");
// file handling
file_name = (char *)malloc(strlen(argv[1]));
file_len = strlen(argv[1]);
memcpy(file_name, argv[1], file_len);
file = fopen(file_name, "rb");
if(file == NULL)
error_handling("File is not exis!\n");
// send file name
h_err = write(sockfd, file_name, file_len);
if(h_err < 0)
error_handling("ERROR writing to socket!\n");
// file handling
fseek(file, 0, 2);
file_len = ftell(file);
fseek(file, 0, 0);
// send file size
memset(buffer, 0, BUFMAX);
sprintf(buffer, "%d", file_len);
h_err = write(sockfd, buffer, strlen(buffer));
if(h_err < 0)
error_handling("ERROR writing to socket!\n");
file_cont = (char *)malloc(file_len);
while( !feof(file) )
{
fgets(buffer, BUFMAX, file);
memcpy(file_cont + buf_size, buffer, strlen(buffer));
buf_size = strlen(buffer);
}
h_err = send(sockfd, file_cont, file_len, 0);
if(h_err < 0)
error_handling("ERROR sending to socket");
printf("File sending....\n");
fclose(file);
close(sockfd);
return 0;
}
Server Source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFMAX 8000
void error_handling(const char *msg)
{
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, h_err;
int file_len = 0;
char buffer[BUFMAX];
struct sockaddr_in serv_addr, cli_addr;
FILE *file;
char *file_name;
char file_cont[BUFMAX];
socklen_t clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error_handling("ERROR opening socket");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(5000);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error_handling("ERROR on binding");
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while(1)
{
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error_handling("ERROR on accept");
// receive file name
memset(buffer, 0x00, BUFMAX);
h_err = read(newsockfd, buffer, BUFMAX);
if (h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR reading from socket");
}
strcpy(file_name, buffer);
printf("File name = %s\n", file_name);
// receive file size
memset(buffer, 0, BUFMAX);
h_err = read(newsockfd, buffer, BUFMAX);
if (h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR reading from socket");
}
file_len = atoi(buffer);
// file handling
file = fopen(file_name, "wb");
h_err = recv(newsockfd, file_cont, file_len, 0);
if(h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR receive from socket");
}
printf("Recived client file\n");
fwrite(file_cont, 1, file_len, file);
close(newsockfd);
}
fclose(file);
close(sockfd);
return 0;
}
I tried to debug your code.
I found that you forget to allocate memory size for var "file_name" in your server code.
Try to allocate for it like following line in your code.
file_name = (char *)malloc(LEN_FILE_NAME);
The problem can be solved.

Server and client program not sending or receiving data

I've been scratching my head with this one for quite a while now. I've got a simple client and server program and I want the server to echo what the client sends it. I can't figure out why the server isn't receiving any data.
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_BUF 64
#define MAX_ARGS 8
void initClient(int*);
int main()
{
int socket;
/* initialize socket and connect to server */
initClient(&socket);
while(1){
char in[80];
char temp[80];
bzero(in, 80);
bzero(temp, 80);
printf("What's your message: ");
gets(in);
strcpy(temp, in);
send(socket, temp, strlen(temp), 0);
if(strcmp(temp, "exit") == 0)
break;
}
return 0;
}
void initClient(int *sock)
{
FILE *configFile;
char ip[MAX_BUF];
int port;
int i;
struct sockaddr_in addr;
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
/* create socket and connect to logger */
sock = (int *)socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock < 0){
printf("Could not open socket\n");
exit(-1);
}
/* setup address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons((unsigned short) port);
/* connect to server */
i = connect((int)sock,
(struct sockaddr *) &addr,
sizeof(addr));
if (i<0) {
printf("client could not connect!\n");
exit(-1);
}
}
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_BUF 64
int main()
{
FILE *configFile;
char ip[MAX_BUF];
int port;
char str[MAX_BUF];
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
int myListenSocket, clientSocket;
struct sockaddr_in myAddr, clientAddr;
int i, addrSize, bytesRcv;
/* Create socket */
myListenSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(myListenSocket < 0) {
printf("Couldn't open socket\n");
exit(-1);
}
/* Set up server address */
memset(&myAddr, 0, sizeof(myAddr));
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
myAddr.sin_port = htons((unsigned short) port);
/* Binding */
i = bind(myListenSocket, (struct sockaddr *) &myAddr, sizeof(myAddr));
if(i < 0){
printf("Couldn't bind socket\n");
exit(-1);
}
/* Listen */
i = listen(myListenSocket, 5);
if(i < 0){
printf("Couldn't listen\n");
exit(-1);
}
/* Wait for connection request */
addrSize = sizeof(clientAddr);
clientSocket = accept(myListenSocket,
(struct sockaddr *) &clientAddr,
&addrSize);
if(clientSocket < 0){
printf("Couldn't accept the connection\n");
exit(-1);
}
/* Read message from client and do something with it */
char buffer[100];
while(1){
bzero(buffer, 100);
bytesRcv = read(clientSocket, buffer, sizeof(buffer));
buffer[bytesRcv] = 0;
printf("this is what the client sent: %s\n", buffer);
if(bytesRcv == 0){
break;
}
}
close(myListenSocket);
close(clientSocket);
return 0;
}
When you pass a pointer you should reference it as *sock to get its value, otherwise if you reference it as sock you are, in fact, getting the address and not the value of the variable.
Here is your initClient function corrected:
void initClient(int *sock)
{
FILE *configFile;
char ip[128];
int port;
int i;
struct sockaddr_in addr;
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
/* create socket and connect to logger */
*sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(*sock < 0){
printf("Could not open socket\n");
exit(-1);
}
/* setup address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons((unsigned short) port);
/* connect to server */
i = connect(*sock, (struct sockaddr *) &addr, sizeof(addr));
if (i<0) {
printf("client could not connect!\n");
exit(-1);
}
}

is it possible to send a respose from udp server to client ?

I posted my code here: communication between windows client and linux server?
I am performing communication between client and server.I know that udp is a connectionless program nothing but it wont send any response back to the client. If i want to send a response back to the client then what should i do ??
I solved all my errors in the above link but I got a doubt w.r.t sending a response back to the client. so i am re posting here.
This is the code I wrote when I start learning socket programming, hope it helps:
server
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct sockaddr_in server;
struct sockaddr_in client;
int socket_fd;
int ret;
char buf[255];
int len = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd < 0)
{
printf("socket error\n");
return -1;
}
server.sin_family = AF_INET;
server.sin_port = htons(5900);
server.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr));
if(ret)
{
printf("error while binding\n");
return -1;
}
ret = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client, &len);
if(ret < 0)
{
printf("reciving error\n");
}
printf("recving data from %s: %s\n", inet_ntoa(client.sin_addr), buf);
snprintf(buf, sizeof(buf), "server:");
ret = sendto(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client, sizeof(client));
if(ret < 0)
{
printf("send error\n");
return -1;
}
close(socket_fd);
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int socket_fd;
struct sockaddr_in server;
int ret;
char buf[255] = "send to server";
int len = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd < 0)
{
printf("socket error\n");
}
server.sin_family = AF_INET;
server.sin_port = htons(5900);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = sendto(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&server, sizeof(server));
if(ret < 0)
{
printf("sendto error\n");
return -1;
}
ret = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&server, &len);
if(ret < 0)
{
printf("error recv from\n");
return -1;
}
printf("recving from server:%s: %s\n", inet_ntoa(server.sin_addr), buf);
close(socket_fd);
}
Read the code above and you will find the answer to your question

Resources