我想读取 tar 文件并使用 C 将其写入另一个 tar 文件。我在这里遵循的过程是:
- 创建文件夹的 tar 文件
- 编写客户端套接字程序,使用 fread 函数在 C 中将 tar 文件读取为二进制文件
- 将缓冲区中的任何内容写入套接字
- 编写服务器套接字程序将发送的数据接收到缓冲区
- 将接收到的缓冲区写入另一个 tar 文件。
- 关闭文件和套接字。
代码如下:
服务器.c
#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;
}
服务器程序的输出:
已创建服务器套接字...
服务器套接字路径设置...
套接字绑定(bind)...
监听套接字...
等待连接...
服务器套接字已连接...
接收: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 写入: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
服务器套接字已关闭...
客户端.c
#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
客户端套接字已关闭...
我正面临这样的问题:
无论我在客户端程序中读取什么,实际发送的只有几个字节,接收函数仍在读取最大字节数。而我希望我的程序读取 1024 个字节,发送 1024 个字节,接收 1024 个字节并写入 1024 个字节,这在这种情况下不会发生。发送缓冲区长度是否有助于解决问题??
是我使用正确的方式通过套接字发送 tar 文件还是有不同的方式?
如何查看数据是否成功读取、发送、接收、写入??
最佳答案
您正在使用 fread
读取二进制文件并像发送字符串一样发送 block :
ret = send(s,buf,strlen(buf),0);
改用它来发送 len
个字节。
ret = send(s,buf,len,0);
同样,服务器程序应该只写入接收到的len
个字节。附加一个'\0'
可能会导致缓冲区溢出并且写入strlen(buf)
字节将无法写入接收到的所有字节,如果收到一个NUL 字节,肯定会这样如果传输的是 tar 文件,则会出现这种情况:
将逻辑更改为:
ret = fwrite(buf,1,len,fp);
您可能还想使用 netcat 实用程序:man nc
关于c - 如何在C中读写tar文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29091786/