Article 4WAYN TCP file transfer in C with socket (server/client),

TCP file transfer in C with socket (server/client),

by
bobbob69420
from LinuxQuestions.org on (#4WAYN)
Hello everyone, Im trying to figure out how to transfer a text file between client and server, through these steps.

1) Have client open text file.
2) have client store text file content in a buffer of chars.
3) Have client send text file to server.

I have skeleton code that does this, but instead of doing a file transfer, it just reverses a string instead.

How would I refactor it into sending a text file to server? And how would I write a function in the client that says the file was successfully sent, and in the server to say that it was received?

On the client side, I had the idea to use

fp = fopen([argv + 1], "r");

to open the file, but Im getting error, (no such file or directory)

client

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#define PORT "3490" // the port client will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once

int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET_ADDRSTRLEN];
FILE *fp;

if (argc != 3) {
fprintf(stderr,"usage: client hostname message\n");
exit(1);
}

/* get info for server */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
/* try to create socket */
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("client: socket");
continue;
}

/* connect socket to server */
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
perror("client: connect");
close(sockfd);
continue;
}
break;
}

if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
return 2;
}

struct sockaddr_in *sa = (struct sockaddr_in *) p->ai_addr;
inet_ntop(AF_INET, &(sa->sin_addr), s, sizeof(s));
printf("client: connecting to %s\n", s);

freeaddrinfo(servinfo); // all done with this structure

/* send message to server */
char *mess = argv[2];
numbytes = write(sockfd, mess, strlen(mess)+1);
if (numbytes != strlen(mess)+1) {
perror("write");
close(sockfd);
exit(0);
}

/* receive message from server */
numbytes = read(sockfd, buf, MAXDATASIZE-1);

buf[numbytes] = '\0';
printf("client: received '%s'\n",buf);

close(sockfd);
return 0;
}
Server Code:

Code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>

#define PORT "3490" // the port users will be connecting to

#define BACKLOG 10 // how many pending connections queue will hold

int main(void)
{
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
int yes=1;
char s[INET_ADDRSTRLEN];
int rv;

/* get info for self, to set up socket */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP

if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop through all the results and bind to the first we can
for (p = servinfo; p != NULL; p = p->ai_next) {
/* try to create socket */
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}

/* set socket options so socket can be reused */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}

/* bind socket to port number */
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}

break;
}

freeaddrinfo(servinfo); // all done with this structure

if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

printf("server: waiting for connections...\n");

while(1) { // main accept() loop
sin_size = sizeof their_addr;
/* block until request arrives */
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}

/* get information about connecting client */
struct sockaddr_in *sa = (struct sockaddr_in *) &their_addr;
inet_ntop(AF_INET, &(sa->sin_addr), s, sizeof(s));
printf("server: got connection from %s\n", s);

if (!fork()) { /* create child to handle new client */
close(sockfd); /* child doesn't need the listener */
char s[80];
/* read string from client */
int numBytes = read(new_fd, s, 80);
if (numBytes > 80) {
perror("read");
close(new_fd);
exit(0);
}
int i, j;
/* reverse string */
for (i=0, j=strlen(s)-1; i<strlen(s)/2; i++, j--) {
char c;
c = s[i];
s[i] = s[j];
s[j] = c;
}
/* send reversed string back to client */
numBytes = write(new_fd, s, strlen(s)+1);
if (numBytes != strlen(s)+1) {
perror("write");
close(new_fd);
exit(0);
}
close(new_fd);
exit(0);
}
close(new_fd); /* parent doesn't need this */
}

return 0;
}latest?d=yIl2AUoC8zA latest?i=JtPWlNaMlfw:owEELcZrAs8:F7zBnMy latest?i=JtPWlNaMlfw:owEELcZrAs8:V_sGLiP latest?d=qj6IDK7rITs latest?i=JtPWlNaMlfw:owEELcZrAs8:gIN9vFwJtPWlNaMlfw
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments