从文件读取并输出到套接字

查克芬利

所以我正在研究一种读取文件并将其内容输出到套接字的方法。

但是,浏览器显示的不是我的简单index.html文件:

#öÇ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

代码:

#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;
}
ALK

改变

int sent = send(sock, &buffer, sizeof buffer, 0);

成为

int sent = send(sock, &buffer, strlen(buffer), 0);

只发送fgets()阅读过的内容。


此外,请注意,send()发送的字节数不必像被告知的那样多。

为了确保一切顺利,请测试send()的结果以查看实际发送了多少,然后循环send()发送其余部分。

来自man send

成功调用后,这些调用将返回发送的字节数。


不会send()返回ssize_tint


同样^ 2,至少是:

int main(void)

另外^ 3:fclose()万一fgets()返回NULL代码将丢失到文件中,一旦到达EOF,它肯定会执行的操作。


最后,最后:serve_file()永远只读取(和发送)文件的第一行。

要解决此更改,此

  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;
  }

看起来像这样

  while ((fgets(buffer, sizeof buffer, file)) != NULL) {
    ...
  }

  if (ferror(file)) {
    printf("Error reading file contents.");
  }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章