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

C 从文件读取并输出到套接字,c,file,sockets,http,file-io,C,File,Sockets,Http,File Io,因此,我正在研究一种方法,该方法读取文件并将其内容输出到套接字 但是,我的浏览器显示的不是简单的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ÿ

因此,我正在研究一种方法,该方法读取文件并将其内容输出到套接字

但是,我的浏览器显示的不是简单的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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义端口8080
#定义协议0
#定义待办事项10
#定义BUFLEN 1500
void serve_文件(int sock,char*filename)
{ 
字符缓冲区[1024];
文件*文件;
//打开文件进行读取
file=fopen(文件名为“rb”);
如果(!文件){
printf(“错误:无法打开文件进行读取”);
返回;
}
如果((fgets(缓冲区,缓冲区大小,文件))!=NULL){
int sent=send(sock,&buffer,sizeof buffer,0);
如果(发送==-1){
printf(“错误:发送到套接字失败\n”);
printf(“错误代码:%s\n”,strerror(errno));
}
}否则{
printf(“错误:无法读取文件内容”);
返回;
}
//再见
fclose(文件);
} 
int main()
{
int-fd;
int connfd;
//对于bind()
地址中的结构sockaddr\u;
//For accept()
cliaddr中的结构sockaddr_;
socklen_t cliaddrlen=sizeof(cliaddr);
//用于阅读和写作
沙祖提;
ssize_t rcount;
字符缓冲区[BUFLEN];
//打开插座
fd=套接字(AF_INET、SOCK_流、协议);
如果(fd==-1){
printf(“错误:无法打开套接字\n”);
printf(“错误代码:%s\n”,strerror(errno));
出口(1);
}
//创建地址
//memset(&addr,0,地址大小);
addr.sin\u addr.s\u addr=INADDR\u ANY;
addr.sin_family=AF_INET;
地址SINU port=htons(端口);
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(“错误:无法绑定\n”);
printf(“错误代码:%s\n”,strerror(errno));
出口(1);
}
//倾听联系
if((侦听(fd,BACKLOG))=-1){
printf(“错误:无法侦听连接\n”);
printf(“错误代码:%s\n”,strerror(errno));
出口(1);
}
//接受连接
connfd=accept(fd,(struct sockaddr*)&cliaddr,&cliaddrlen);
如果(connfd==-1){
printf(“错误:无法接受连接\n”);
printf(“错误代码:%s\n”,strerror(errno));
出口(1);
}
//读取数据
rcount=读取(connfd,buffer,BUFLEN);
如果(rcount==-1){
printf(“错误:无法接受连接\n”);
printf(“错误代码:%s\n”,strerror(errno));
出口(1);
}
对于(i=0;i
更改

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

int sent = send(sock, &buffer, strlen(buffer), 0);
只发送
fgets()
读取的内容


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

为了确保所有东西都被发送,测试结果以查看实际发送了多少,并循环
send()
发送其余的内容

发件人:

成功时,这些调用返回发送的字节数


另外
send()
返回
ssize\u t
not
int


此外^2至少:

int main(void)

另外^3:如果
fgets()
返回
NULL
,则代码将丢失文件
fclose()


还有^最后:
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.");
  }
改变

将来

int sent = send(sock, &buffer, strlen(buffer), 0);
只发送
fgets()
读取的内容


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

为了确保所有东西都被发送,测试结果以查看实际发送了多少,并循环
send()
发送其余的内容

发件人:

成功时,这些调用返回发送的字节数


另外
send()
返回
ssize\u t
not
int


此外^2至少:

int main(void)

另外^3:如果
fgets()
返回
NULL
,则代码将丢失文件
fclose()


还有^最后:
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.");
  }
改变

将来

int sent = send(sock, &buffer, strlen(buffer), 0);
只发送
fgets()
读取的内容


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

为了确保所有东西都被发送,测试结果以查看实际发送了多少,并循环
send()
发送其余的内容

发件人:

成功时,这些调用返回发送的字节数


另外
send()
返回
ssize\u t
not
int


此外^2至少:

int main(void)

另外^3:如果
fgets()
返回
NULL
,则代码将丢失文件
fclose()


还有^最后:
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.");
  }
改变

将来

int sent = send(sock, &buffer, strlen(buffer), 0);
只发送
fgets()
读取的内容


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

为了确保所有东西都被发送,测试结果以查看实际发送了多少,并循环
send()
发送其余的内容

发件人:

成功时,这些调用返回发送的字节数


另外
send()
返回
ssize\u t
not
int


此外^2至少:

int main(void)

另外^3:如果
fgets()
返回
NULL
,则代码将丢失文件
fclose()


还有^Finally: