c - 读取 C 中文件传输的可执行文件的字符

标签 c sockets file-io

所以最近为了一个类(class)项目,我决定自己制作一个程序,可以通过局域网传输文件并将其集成到 linux 操作系统中(在这种情况下,我所做的只是将它添加到上下文菜单中)使用套接字服务器。

它的工作方式本质上是,

Server is waiting.
Client connects.
Client sends a message of 1024 length with the first 4 characters reserved
The first 4 characters are used to store an int which will state the length of the message

server recieves them, writes them, then waits for the next block
when the server recieves a message where the length is 0  
it ends the transfer and closes the files

这完美地适用于文本文件。由于有用的反馈,我对上一个代码进行了改进,我已经设法创建了操作系统实际识别文件扩展名的东西,无论类型如何。然而,对于像 png 这样的东西,它们显示为黑色,对于 exe,它们会立即出现段错误。

无论文件类型如何,我都可以在阅读和写作方面做出哪些改变才能使其正常工作?我不确定去哪里,因为我所拥有的应该可以工作

附加信息:我正在用 C 编写代码。要打开文件,我使用 fopen、fgetc 和 fputc。 这是我为我的服务器编写的代码:

          while (1){

     n = read(newsockfd,message,1024);
     if (n < 0) {
        fclose(fptr2);
        error("ERROR reading from socket");
        }
    //The first 4 bytes/characters are used to store the length.
    //I read them by getting a pointer to the first char and then reading it as
    //an int by casting it. This works with no problem
    char *p=&message;
    int *p2=(int*)p;
    int length=*p2;
     //Checks if the length is 0, if so, exit
     if (length==0)
        break;
    //writes to the file
        for (int i=4;i<length;i++){
          fputc(message[i], fptr2);
    }

     n = write(newsockfd,"Ready",5);
     if (n < 0) 
         error("ERROR writing to socket");
     bzero(message,255);
     }

     fclose(fptr2);
     //n = write(newsockfd,"I got your message",18);
     //if (n < 0) error("ERROR writing to socket");
     printf("Done.\n");
     return 0; 
}

从我的客户端执行,它读取文件然后发送它。

    while (finished!=0&&c!=EOF)
{

   for (int i =4;i<1024;i++)
   {
       if (c==EOF)
       {
    char* p=&message;
    int* pi=(int*)p;
    *pi=i;
    finished=0;
    //printf("length is:%d\n",i);
    break;
    }
    //printf("%c",c);
       message[i]=c;
       //fputc(c, fptr2);
       c = fgetc(fptr1);    
   }
if (finished!=0) 
{
char* p=&message;
int* pi=(int*)p;
*pi=1024;
}
   n = write(sockfd,message,1024);
   if (n < 0) 
     {
       fclose(fptr1);
       error("ERROR writing to socket");
     }
   bzero(message,1024);
   //reading
   n = read(sockfd,buffer,255);
  if (n < 0) 
     error("ERROR reading from socket");
}

最佳答案

0x00 是二进制文件的有效字符,因此当您看到一个字符时您不能“停止”[就像对于字符串一样]。

您正在使用数据包的第一个字符作为 EOF 标记(即非零表示有效数据,零表示 EOF)。但是,请注意数据包中的第一个数据字符可能为零,因此您必须使用其中没有数据字符的单字节“ header ”,仅使用“停止”标志字符 [如果您愿意]:

while (1) {
    // Reading
    n = read(newsockfd, message, 1023);
    if (n < 0) {
        fclose(fptr2);
        error("ERROR reading from socket");
    }

    // Checks if the first character is null, if so, exit
    if (message[0] == 0)
        break;

    // writes to the file
    // NOTE: now the data starts at offset 1!
    int i = 1;
    for (;  i < n;  ++i) {
        fputc(message[i], fptr2);
    }

    i = 0;
    n = write(newsockfd, "Ready", 5);
    if (n < 0)
        error("ERROR writing to socket");
    bzero(message, 1023);
}

fclose(fptr2);

但是,更简单的方法是读取直到长度返回零:

while (1) {
    // Reading
    n = read(newsockfd, message, 1024);

    // end of data
    if (n == 0)
        break;

    // error
    if (n < 0) {
        fclose(fptr2);
        error("ERROR reading from socket");
    }

    // writes to the file
    fwrite(message,1,n,fptr2);

    i = 0;
    n = write(newsockfd, "Ready", 5);
    if (n < 0)
        error("ERROR writing to socket");
    bzero(message, 1023);
}

fclose(fptr2);

关于c - 读取 C 中文件传输的可执行文件的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49500792/

相关文章:

java - 简化在 .jar 所在文件夹中打开文件的过程

r - 如何合并 R 中嵌套文件夹中的 csv 文件

java - 使用 nio 创建文件时出现 NoSuchFileException

c - 如何在 C 中手动迭代堆栈帧?

java - OutputStreamWriter.flush() 延迟

python - 被 Python 中的 read_all() 函数困住了吗?

c - 使用 Scapy 与 C 套接字通信

c - C 中嵌套 for 循环的非常奇怪的问题,数据不一致

c - strcmp 比较下注预定义和接收到的字符串

C 另一个指针的指针