Reputation: 2595
so i am working on a method that reads in a file and outputs its contents to a socket.
However, instead of my simple index.html file my browser shows this:
#öÇdÿ GÊdÿ(˜ÊdÿÎ+Yÿ@0Çdÿ ŸÊdÿÐÎ+YÿÍ×ÇdÿHÌÊdÿèÌÊdÿ@Î+YÿlñÇdÿ ŸÊdÿ8öŒÿ¶¢ð‘ÿÎ+YÿòXÈdÿ GÊdÿ ŸÊdÿؾÊdÿâ@”ÐÎ+YÿŠÈdÿ Ð+Yÿ ŸÊdÿ ²Êdÿâ@”Ï+YÿŠÈdÿ Ð+YؾÊdÿ°0ÊdÿؾÊdÿ°0Êdÿ°0Êdÿ ŸÊdÿ`Ï+Yÿ¡Èdÿ°0Êdÿ ŸÊdÿ°0Êdÿâ@” Ð+Yÿ°Ï+YÿcbÈdÿ Ð+Yÿ¼À‡¨Qµpÿ8A”ë@”p0” ŸÊdÿPÐ+Yÿ¨ ®ÿ «ª2Ð+Yÿ©$®ÿ„Ð+Yÿ€Ð+Yÿ|Ð+Yÿ†Æuÿ€¸†Æuÿ€wÈ` †ÆuÿèƒÆuÿ yÆuÿ†Æuÿ Ð+Yÿó(®ÿU«""öèƒÆu` ƒƒèƒÆuÿ/”ÐÐ+YÿÕ;$ŒÿèƒÆuÿ/”ôÆuÿÐÑ+Yÿ$Œÿ †ÆuÿU«""ö@Ð+Yÿin:/bin:/usr/sbin:/sbin:/usr/locusr/local/bin:/usr/local/git/bin0àÑ+YÿàÐ+Yÿusername
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 8080
#define PROTOCOL 0
#define BACKLOG 10
#define BUFLEN 1500
void serve_file(int sock, char* filename)
{
char buffer[1024];
FILE *file;
// Open file for reading
file = fopen(filename, "rb");
if (!file) {
printf("Error: can't open file for reading");
return;
}
if ((fgets(buffer, sizeof buffer, file)) != NULL) {
int sent = send(sock, &buffer, sizeof buffer, 0);
if (sent == -1) {
printf("Error: send to socket failed\n");
printf("Error code: %s\n", strerror(errno));
}
} else {
printf("Error: could not read file contents");
return;
}
// Bye
fclose(file);
}
int main()
{
int fd;
int connfd;
// For bind()
struct sockaddr_in addr;
// For accept()
struct sockaddr_in cliaddr;
socklen_t cliaddrlen = sizeof(cliaddr);
// For reading and writing
ssize_t i;
ssize_t rcount;
char buffer[BUFLEN];
// Open a socket
fd = socket(AF_INET, SOCK_STREAM, PROTOCOL);
if (fd == -1) {
printf("Error: unable to open a socket\n");
printf("Error code: %s\n", strerror(errno));
exit(1);
}
// Create an address
//memset(&addr, 0, sizeof addr);
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
int yes = 1;
if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1 )
{
perror("setsockopt");
}
if ((bind(fd, (struct sockaddr *)&addr, sizeof(addr))) == -1) {
printf("Error: unable to bind\n");
printf("Error code: %s\n", strerror(errno));
exit(1);
}
// Listen for connections
if ((listen(fd, BACKLOG)) == -1) {
printf("Error: unable to listen for connections\n");
printf("Error code: %s\n", strerror(errno));
exit(1);
}
// Accept connections
connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
if (connfd == -1) {
printf("Error: unable to accept connections\n");
printf("Error code: %s\n", strerror(errno));
exit(1);
}
// Read data
rcount = read(connfd, buffer, BUFLEN);
if (rcount == -1) {
printf("Error: unable to accept connections\n");
printf("Error code: %s\n", strerror(errno));
exit(1);
}
for (i = 0; i < rcount; i++) {
printf("%c", buffer[i]);
}
//write(connfd, buffer, rcount);
serve_file(connfd, "index.html");
// Bye
close(connfd);
return 0;
}
Upvotes: 0
Views: 70
Reputation: 70981
Change
int sent = send(sock, &buffer, sizeof buffer, 0);
to be
int sent = send(sock, &buffer, strlen(buffer), 0);
to only send what fgets()
did read.
Moreover, be aware, that send()
does not necessarly sends as much bytes as it was told to do.
To make sure everthing is sent, test send()
's result to see how much actual was send and loop around send()
to send the rest.
From man send
:
On success, these calls return the number of bytes sent.
Also send()
returns ssize_t
not int
.
Also^2 it's at least:
int main(void)
Also^3: The code misses to fclose()
the file in case fgets()
returned NULL
, what it defintily will do when it reached EOF.
Also^Finally: serve_file()
ever only reads (and sends) the file's first line.
To fix this change this
if ((fgets(buffer, sizeof buffer, file)) != NULL) {
int sent = send(sock, &buffer, sizeof buffer, 0);
if (sent == -1) {
printf("Error: send to socket failed\n");
printf("Error code: %s\n", strerror(errno));
}
} else {
printf("Error: could not read file contents");
return;
}
to look like this
while ((fgets(buffer, sizeof buffer, file)) != NULL) {
...
}
if (ferror(file)) {
printf("Error reading file contents.");
}
Upvotes: 3