如何在客户端 - 服务器应用程序中异步发送文件?(使用winsock2.h,在C中)

问题描述 投票:1回答:2

我想异步发送文件。我开始发送文件client-> server->另一个客户端,但如果我想发送一个非常大的文件,客户端不能发送任何其他命令到服务器,直到文件完全发送。对于客户端想要发送的每个文件,我创建一个新线程,我将一次读取1kb的文件并发送到服务器,然后服务器将收到1kb并进一步发送到所需的客户端。问题是当客户端发送文件时,套接字已满,包含来自服务器的字节。我应该为我想发送的每个文件创建一个客户端 - 服务器套接字?我尝试了一切,但没有什么是成功的。

c sockets asynchronous send
2个回答
2
投票

为每次传输创建专用套接字是一种解决方案,除非同时连接的数量很大(系统上只有这么多IP端口,服务器需要两倍),否则它不会很糟糕。线程并没有像你想象的那样简化这一过程,而是介绍了自己的挑战; select是一种从单个线程/进程有效地在多个套接字上传输数据的简单方法。它的工作原理是暴露底层操作系统知道哪些套接字可以读取和写入程序。

无论线程选择如何,使用多插槽方法的挑战是服务器必须告诉收件人为每次新传输打开一个新的连接回服务器。现在您需要一个命令mechansim来告诉收件人为下一个文件打开一个新连接。

另一个选择是只打开一个套接字,但通过套接字同时发送多个文件。您可以通过发送包含每个文件的下一部分的数据结构来完成此操作,而不是直接直接流式传输文件。例如,您可能会发送一条类似于此内容的消息(为了清楚起见,以JSON格式呈现,但它将是一种有效的传输格式):

[ 
  { 
    "name": "file.txt", 
    "bytes": "some smallish chunk of content", 
    "eof": false
  },
  { 
    "name": "another.txt", 
    "bytes": "chunk of another.txt content", 
    "eof": true
  }
]

这个例子当然是天真的简单化,但希望它足以让我们了解:通过构造你发送的消息,你可以描述哪些文件,哪些字节块属于哪个,然后一次发送多个文件的多个块。由于您的客户端 - >服务器 - >客户端方法,这似乎是我的最佳途径。


0
投票

使用类似于的结构:

struct transferPacket
{
    unsigned packetOfFile;  // = 0 when starting a new file
    unsigned fileNumber;    // incremented with each new file
    unsigned byteCount; 
    char     payload[ MAX_PAYLOAD_LEN ];
};

当packetOfFile == 0然后启动新文件和有效负载包含文件名否则指示文件的哪个部分正在被传输。

当byteCount = 0时,则为该fileNumber的EOF

以上只需要一个TCP套接字

可以一次传输多个文件。接收方知道数据包属于哪个文件以及有效负载所属的文件中的哪个位置。

发送方每次发送相同数量的字节,除了文件的第一个数据包和EOF数据包或文件的最后一个数据包

© www.soinside.com 2019 - 2024. All rights reserved.