Reputation: 67
I'm having a little issue going from (plain text) stream sockets to "something" that can send files. A month ago I wrote a basic chat client. Now I wish to be able to send and receive a file of any type. Lets go with PDFs or and Image. I'm going to list what resources I am using, and what I "think" is the right direction. I just need help connecting the dots.
From my research it looks like I need to first take the file, convert it to binary, and send it over . I'm guessing I want a TCP style, as I care greatly if a file's packet come in order / comes at all.
I have read Beej.us on sockets. Which I also did not find a section for sending data. I did find the section on sending different "data types" ie float, etc.
I'm guessing I want a "datagram" not a stream. I do have my copy of Unix Networking Programing if one knows the section in this book. I failed to find a section that looks anything like . After 2, 3 hours of research I'm really not finding anything that is simple or clear. Mostly just unanswered forum questions..
This is what I would start off with. Later I would alter it with custom IPs, ports etc. Taking from Beej for a datagram - sender. Which sends text from a command line argument..
#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 <arpa/inet.h>
#include <netdb.h>
#define SERVERPORT "4950" // the port users will be connecting to
int main(int argc, char *argv[])
{
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
int numbytes;
if (argc != 3) {
fprintf(stderr,"usage: talker hostname message\n");
exit(1);
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; // datagrams..
if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket.
//I'm not sure about the need for a loop
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "talker: failed to bind socket\n");
return 2;
}
// here is where we would send a file. Lets say ./img.png
// If I had to guess I'd need to write a custom packet, turn the file into binary, then to
//a packet. Then call send while we still have packets.
// Am I on the right track?
if ((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0,
p->ai_addr, p->ai_addrlen)) == -1) {
perror("talker: sendto");
exit(1);
}
freeaddrinfo(servinfo);
printf("talker: sent %d bytes to %s\n", numbytes, argv[1]);
close(sockfd);
return 0;
}
Upvotes: 0
Views: 452
Reputation: 68023
Ah, where to start....?
First off, You'll want TCP (streams), not UDP (datagrams). Datagrams are limited in size, and UDP is inherently unreliable.
Second, "converting your file to binary" : I think you'll find that's how it's stored on disk. ;-)
Third, You'll probably want to send some kind of header before the actual file. The header would typically include things like the file name, file size, and something that allows you to distinguish it from any other messages (chat?) that you're sending over the same port.
The header could be a fixed-size chunk of binary data, or something readable more like the HTTP headers.
Upvotes: 1