【问题标题】:How do i send a .bmp file using socket apis in c at one go?如何一次性使用 c 中的套接字 API 发送 .bmp 文件?
【发布时间】:2012-05-24 20:44:55
【问题描述】:

我有一个文件 pict.bmp 我需要通过 LAN 发送。有一个服务器开始监听端口。客户端与服务器建立连接后,它请求服务器提供文件的文件名.服务器然后使用文件名并发送给客户端。但是问题是服务器使用sendfile()系统调用成功发送它但是文件没有出现在客户端运行的目录中。有没有更好的做到这一点的方法,即实现相同目的的其他一些系统调用。我在这里复制粘贴发送接收部分:

服务器:

 while(1){

                    nsd = accept(sd,(struct sockaddr*)&clit,&clen);

                    if(nsd < 0){

                            eMsg("Accept error");

                    }

                    rc = recv(nsd, filename, sizeof(filename), 0);

                    if (rc < 0) {

                            eMsg("Receive error");

                    }

                    printf("Filename : %s\n",filename);

                    filename[strlen(filename) - 1] = '\0';

                    if (strcmp(filename, "quit") == 0) {

                            fprintf(stderr, "quit command received, shutting down server\n");

                            break;
                    }

                    fd = open("2bird.bmp", O_RDONLY);

                    printf("fd is %d\n",fd);

                    if (fd < 0) {

                            eMsg("File Open error");

                    }

                    offset = 0;

                    rc = sendfile (nsd, fd, NULL, 1);

                    if (rc < 0) {

                        eMsg("File Send error");

                        fprintf(stderr,"Sending failed");

                }

                if (rc != stat_buf.st_size) {

                        eMsg("File Transfer error");

                }

                close(fd);

                close(nsd);

客户:

bzero((char *) &serv_addr, sizeof(serv_addr));
     39
     40         serv_addr.sin_family = AF_INET;
     41
     42         bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,server->h_length);
     43
     44         serv_addr.sin_port = htons(atoi(argv[2]));
     45
     46         if (connect(sd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
     47
     48                 eMsg("Connection error");
     49
     50         }
     51
     52         printf("Please enter the filename : ");
     53
     54         bzero(buffer,256);
     55
     56         fgets(buffer,255,stdin);
     57
     58         n = write(sd,buffer,strlen(buffer));
     59
     60         if (n < 0)
     61
     62         error("Writing To Socket error");
     63
     64
     65         close(sd);
     66
     67         return 0;
     68
     69 }
     70
     71 void eMsg(char *M){
     72
     73         perror(M);

【问题讨论】:

  • 请让我知道客户端程序应该是什么样的?
  • 如果失败的是客户端部分,那么是的,请发布相关部分。请尝试改进格式,如果可以的话,您发布的内容中的缩进都很奇怪。
  • 行号使情况变得更糟。您保存到客户端文件的代码在哪里?
  • filename[strlen(filename) - 1] = '\0'; 很危险。 strlen() 可能为零。另外:文件名不需要以 nul 结尾。客户端发送strlen(buffer),它是长度没有NUL(但它确实包含一个'\n',它不是NUL)
  • 潜在问题是您假设 TCP 流中的消息边界。没有消息边界。处理它。

标签: c linux sockets unix tcp


【解决方案1】:

如我所见,在服务器上,您调用了 sendfile(),它将数据从 fd(bmp 文件的文件描述符)复制到 nsd(套接字)。因此,您已将文件内容复制到套接字描述符。但是要在客户端获取此内容,您必须在客户端从该套接字接收数据。

由于您没有这样做,这就是您没有在客户端获取文件的原因。

【讨论】:

    【解决方案2】:

    插入 e。 g.

        buffer[strcspn(buffer, "\n")] = '\0';
        int fd = open(buffer, O_CREAT|O_WRONLY, 0666);
        while (n = read(sd, buffer, 256), n > 0) write(fd, buffer, n);
        close(fd);
    

    之前

        close(sd);
    

    (要添加错误检查)。当然,更高阶的缓冲区大小会更有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多