首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在C中读写tar文件?

如何在C中读写tar文件?
EN

Stack Overflow用户
提问于 2015-03-17 05:18:51
回答 2查看 3.1K关注 0票数 0

我想使用C读取tar文件并将其写入另一个tar文件。下面的步骤如下:

  1. 创建文件夹的tar文件
  2. 使用fread函数编写客户端套接字程序,将tar文件读入C中的二进制文件
  3. 将缓冲区中的任何内容写入套接字
  4. 编写服务器套接字程序以将发送的数据接收到缓冲区
  5. 将接收到的缓冲区写入另一个tar文件。
  6. 关闭文件和套接字。

这是代码:

Server.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define MAX 1024
#define SOCK_PATH "/tmp/foo"

int s, s2, t, len;
struct sockaddr_un local, remote;

void createSSocket()
{
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
    {
        perror("socket");
        exit(1);
    }
    printf("\nServer Socket Created...");
}

void setSSocketPath()
{
    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH);
    unlink(local.sun_path);
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    printf("\nServer Socket Path Set...");
}

void bindSocket()
{
    if (bind(s, (struct sockaddr *)&local, len) == -1) 
    {
        perror("bind");
        exit(1);
    }
    printf("\nSocket Binded...");
}

void listenSocket()
{   
    if (listen(s, 5) == -1) 
    {
        perror("listen");
        exit(1);
    }
    printf("\nListening Socket...");
}

void acceptConnection()
{
    printf("\nWaiting for a connection...");
    t = sizeof(remote);
    if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) 
    {
        perror("accept");
        exit(1);
    }
    printf("\nServer Socket Connected...");
}

void closeSSocket()
{
    close(s);
    close(s2);
    printf("\nServer Socket Closed...");
}


void receiveTar()
{
    int len,ret;
    char buf[MAX] = {0};
    char path[MAX] = "/home/priyanka/Codes/3455.tgz";
    FILE* fp;
    fp = fopen(path,"wb");

    while((len = recv(s2,buf,MAX,0)) > 0)
    {
        buf[len] = 0;
        printf("\nReceived : %d",len);
        //fputs(buf,fp);
        //printf("%s",buf);
        ret = fwrite(buf,1,strlen(buf),fp);
        if(ret == -1)
        {
            perror("Error writing to file");
        }
        printf("    Write : %d",ret);
    }
    fclose(fp);
}

int main()
{
    createSSocket();    
    setSSocketPath();
    bindSocket();
    listenSocket();
    acceptConnection(); 

    receiveTar();

    closeSSocket();
    return 0;   
}

服务器程序输出:

服务器套接字创建..。

服务器套接字路径集..。

套接字绑定..。

监听插座..。

等待联系..。

服务器套接字连接。

收到: 1024写信: 1024

收到: 459封信: 459封

收到: 239封信函: 239封

收到: 529封信: 529封

收到: 425封信: 425封

收到: 411写: 411

收到: 493封信: 493封

收到: 142封信: 142封

收到: 1024写信: 1024

收到: 397写信: 397

收到: 41封信: 41封

收到: 158封信: 158封

收到: 1024写信: 1024

收到: 705写信: 705

收到: 505封信: 505封

收到: 1024写信: 1024

收到: 87封信: 87封

收到: 1024写信: 1024

收到: 326封信

收到: 234封信: 234封

收到: 311写信: 311

收到: 819写信: 819

收到: 571写信: 571

收到: 1024写信: 1024

收到: 1024写信: 1024

收到: 341封信: 341封

收到: 243封信: 243封

收到: 630封信: 630封

收到: 50封信: 50封

收到: 35封信: 35封

收到: 215封信: 215封

服务器套接字关闭。

Client.c

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define MAX 1024
#define SOCK_PATH "/tmp/foo"


int s, t, len;
struct sockaddr_un remote;

void createCSocket()
{
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
    {
        perror("socket");
        exit(1);
    }
    printf("\nClient Socket Created...");
}

void setCSocketPath()
{
    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
    printf("\nClient Socket Path Set...");
}

void connectSocket()
{
    printf("\nTrying to connect...");
    if (connect(s, (struct sockaddr *)&remote, len) == -1) 
    {
        perror("connect");
        exit(1);
    }
    printf("\nClient Connected...\n");
}

void closeCSocket()
{
    close(s);
    printf("\nClient Socket Closed...");
}

void sendTar()
{
    FILE *fp;
    int ret,len;
    char buf[MAX] = {0};
    fp = fopen("/home/priyanka/3455.tgz","rb");
    while(len = fread(buf,1,1024,fp))
    //while((buf[0] = fgetc(fp)) != EOF)
    {
        printf("\nRead : %d",len);
        ret = send(s,buf,strlen(buf),0);
        printf("    Sent : %d",ret);
        if(ret == -1)
        {
            perror("Error sending data : Client");
        }
    }
    fclose(fp);
}

int main()
{
    createCSocket();
    setCSocketPath();
    connectSocket();

    sendTar();

    closeCSocket(); 
    return 0;
}

客户程序输出:

客户端套接字创建..。

客户套接字路径集..。

试图连接..。

客户联系..。

读: 1024发送:3

读作: 1024发送: 1027

读作: 1024发送: 273

读: 1024发送: 180

读: 1024发送: 239

读作: 1024发送: 529

读作: 1024发送: 425

读: 1024发送: 411

读作: 1024发送: 493

读: 1024发送: 142

读作: 1024发送: 1027

读: 1024发送: 394

读作: 1024发送: 41

读: 1024发送: 158

读作: 1024发送: 702

读作: 1024发送: 1027

读作: 1024发送: 503

读作: 1024发送:2

读作: 1024发送: 1027

读作: 1024发送: 84

读作: 1024发送: 1027

读作: 1024发送: 323

读作: 1024发送: 234

读作: 1024发送: 311

读作: 1024发送: 819

读作: 1024发送: 571

读作: 1024发送: 1027

读作: 1024发送: 1027

读作: 1024发送: 335

读作: 1024发送: 243

读: 1024发送: 630

读作: 1024发送: 50

读作: 1024发送: 35

读作: 315发送: 215

客户插座关闭..。

我面临的问题如下:

  1. 不管我在客户端程序中读取什么,实际上只发送了几个字节,而接收函数仍然是读取最大字节数。而我希望我的程序读取1024字节,发送1024字节,接收1024字节,写1024字节,在本例中不是这样。发送缓冲区长度是否有助于解决问题??
  2. 是用正确的方式通过套接字发送tar文件,还是有不同的方法?
  3. 如何检查数据是否被成功读取、发送、接收和写入??
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-17 05:53:52

您正在使用fread读取二进制文件,并像发送字符串一样发送块:

代码语言:javascript
复制
        ret = send(s,buf,strlen(buf),0);

使用它只发送len字节。

代码语言:javascript
复制
        ret = send(s,buf,len,0);

类似地,服务器程序应该只编写接收到的len字节。追加'\0'可能会导致缓冲区溢出,如果接收到NUL字节,写入strlen(buf)字节将无法写入接收的所有字节,就像传输tar文件一样:

将逻辑更改为:

代码语言:javascript
复制
    ret = fwrite(buf,1,len,fp);

您还可能希望使用netcat实用程序:man nc

票数 2
EN

Stack Overflow用户

发布于 2015-03-17 05:56:46

有几个版本的柏油,一个用于读取和写入C中的tar归档文件的库。

如果通过tcp(7) 插座(7) (例如在Linux或POSIX上)使用网络,请记住,TCP/IP只是一个没有任何消息概念的字节流:发射端的发送(2) (或write)操作不一定与接收端的单个recv(2) (或read)操作相对应,“数据包”可能已经被分割或重新组装(例如,由中间路由器或网络硬件或控制器或内核层)。因此,您始终应该缓冲和管理部分readsendwriterecv操作的字节计数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29091786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档