简体   繁体   English

如何在C Sharp中同时通过tcp发送多个文件?

[英]How do I send multiple files over tcp at the same time in c sharp?

I have a tcp client - server implementation running in the same program, on different background worker threads. 我有一个tcp客户端-服务器实现在同一程序中在不同的后台工作线程上运行。 There will be instances of this program on multiple computers so they can send and receive files between each other. 多台计算机上都会有该程序的实例,因此它们可以在彼此之间发送和接收文件。 I can send files sequentially between computers using network stream, but how would I send multiple files at the same time from computer A to B. 我可以使用网络流在计算机之间顺序发送文件,但是如何同时从计算机A到B发送多个文件。

Sending multiple files over one connection ( socket ) is fine, but having multiple network streams sending data to a client, the client doesn't know which chunk of data is apart of which file ? 通过一个连接(套接字)发送多个文件很好,但是由于有多个网络流向客户端发送数据,客户端不知道哪个数据块与哪个文件分开?

Would it be possible for the client to connect twice to the server (on a difference port, as a 'random'/ unused port is assigned to the connection) and then each connection have its own stream, allowing 2 files to be sent at the same time? 客户端是否有可能两次连接到服务器(在另一个端口上,因为为连接分配了“随机” /未使用的端口),然后每个连接都有自己的流,从而允许在服务器上发送2个文件同时?

Thanks for your time and effort. 感谢您的时间和精力。

The client could certainly connect to the server multiple times - and probably should. 客户端当然可以多次连接到服务器-也许应该。

You can specify the same server port though - a different local port will be assigned at the server side, but the client doesn't need to know about that. 不过,您可以指定相同的服务器端口-在服务器端将分配一个不同的本地端口,但是客户端不需要知道这一点。 (Think about a web server - lots of clients will all connect to port 80 at the same time.) (考虑一下Web服务器- 许多客户端都将同时连接到端口80。)

You'll automatically be assigned separate client side ports as well, of course - basically the connections shouldn't interfere with each other at all. 当然,也将自动为您分配单独的客户端端口-基本上,连接根本不会相互干扰。

You need to use Asyncronous Client and server sockets. 您需要使用异步客户端和服务器套接字。 Basically instead of using Recieve and Send, use BeginRecieve, BeginSend, BeginConnect and BeginAccept. 基本上,而不是使用接收和发送,而是使用BeginRecieve,BeginSend,BeginConnect和BeginAccept。 That way the threading is done for you. 这样,线程就可以为您完成。 Having each connection in a worker thread is not a good idea. 在工作线程中具有每个连接不是一个好主意。 This way each new request is handled at the same time(asycronously). 这样,每个新请求都可以同时(异步)处理。 You can also use the first few bytes of your sent file to store data about the file. 您还可以使用已发送文件的前几个字节来存储有关该文件的数据。 Example below. 下面的例子。 Of course the numbers(1,2,3..) below would be a string filename that you called Bitconverter.GetBytes(String var) on. 当然,下面的数字(1,2,3 ..)将是您在其上调用Bitconverter.GetBytes(String var)的字符串文件名。 hope this helps. 希望这可以帮助。 maxpfc@gmail.com (skype) maxpfc@gmail.com(skype)

byte[] completefile = [1,2,3,4,5,6,7,8,9];
byte[] filename;
filename = split(lcomplefile, 3);  

Below is a compilable example of Asyc Sockets. 以下是Asyc套接字的可编译示例。

using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
class AsyncTcpClient Form:
{
private TextBox newText;
private TextBox conStatus;
private ListBox results;
private Socket client;
private byte[] data = new byte[1024];
private int size = 1024;
public AsyncTcpClient()
{
Text = "Asynchronous TCP Client";
Size = new Size(400, 380);
Label label1 = new Label();
label1.Parent = this;
label1.Text = "Enter text string:";
label1.AutoSize = true;
label1.Location = new Point(10, 30);
newText = new TextBox();
newText.Parent = this;
newText.Size = new Size(200, 2 * Font.Height);
newText.Location = new Point(10, 55);
results = new ListBox();
results.Parent = this;
results.Location = new Point(10, 85);
results.Size = new Size(360, 18 * Font.Height);
Label label2 = new Label();
label2.Parent = this;
label2.Text = "Connection Status:";
label2.AutoSize = true;
label2.Location = new Point(10, 330);
conStatus = new TextBox();
conStatus.Parent = this;
conStatus.Text = "Disconnected";
conStatus.Size = new Size(200, 2 * Font.Height);
conStatus.Location = new Point(110, 325);
This document is created with the unregistered version of CHM2PDF Pilot
Button sendit = new Button();
sendit.Parent = this;
sendit.Text = "Send";
sendit.Location = new Point(220,52);
sendit.Size = new Size(5 * Font.Height, 2 * Font.Height);
sendit.Click += new EventHandler(ButtonSendOnClick);
Button connect = new Button();
connect.Parent = this;
connect.Text = "Connect";
connect.Location = new Point(295, 20);
connect.Size = new Size(6 * Font.Height, 2 * Font.Height);
connect.Click += new EventHandler(ButtonConnectOnClick);
Button discon = new Button();
discon.Parent = this;
discon.Text = "Disconnect";
discon.Location = new Point(295,52);
discon.Size = new Size(6 * Font.Height, 2 * Font.Height);
discon.Click += new EventHandler(ButtonDisconOnClick);
}
void ButtonConnectOnClick(object obj, EventArgs ea)
{
conStatus.Text = "Connecting...";
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
}
void ButtonSendOnClick(object obj, EventArgs ea)
{
byte[] message = Encoding.ASCII.GetBytes(newText.Text);
newText.Clear();
client.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
void ButtonDisconOnClick(object obj, EventArgs ea)
{
client.Close();
conStatus.Text = "Disconnected";
}
void Connected(IAsyncResult iar)
{
client = (Socket)iar.AsyncState;
try
{
client.EndConnect(iar);
conStatus.Text = "Connected to: " + client.RemoteEndPoint.ToString();
client.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), client);
} catch (SocketException)
{
conStatus.Text = "Error connecting";
}
}
void ReceiveData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceive(iar);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
results.Items.Add(stringData);
}
void SendData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int sent = remote.EndSend(iar);
remote.BeginReceive(data, 0, size, SocketFlags.None,
This document is created with the unregistered version of CHM2PDF Pilot
new AsyncCallback(ReceiveData), remote);
}
public static void Main()
{
Application.Run(new AsyncTcpClient());
}
}

Would it be possible for the client to connect twice to the server (on a difference port, as a 'random'/ unused port is assigned to the connection) and then each connection have its own stream, allowing 2 files to be sent at the same time? 客户端是否有可能两次连接到服务器(在另一个端口上,因为为连接分配了“随机” /未使用的端口),然后每个连接都有自己的流,从而允许在服务器上发送2个文件同时?

Yes; 是; this is how network protocols typically work. 这就是网络协议通常的工作方式。 You don't need to choose a new port number on the server side: even if you listen on a fixed port number, connections to that port are kept separate. 您无需在服务器端选择新的端口号:即使您侦听固定端口号,该端口的连接也保持独立。

For instance, the web server at www.stackoverflow.com always listens on port 80, yet you and I can connect from our web browsers, and our connections don't get mixed up. 例如,www.stackoverflow.com上的Web服务器始终在端口80上侦听,但是您和我可以通过我们的Web浏览器进行连接,并且我们的连接不会混淆。

You could do that, but I don't see the benefit. 您可以这样做,但是我看不到好处。 Unless the each connection is throttled somewhere down the line, you are essentially incurring twice the overhead of your I/O operations. 除非每个连接在线路的某个位置受到限制,否则实际上将导致I / O操作开销的两倍。

It's the same as writing a file to a disk, just because you split it to two threads doesn't mean it will be faster, because the disk can only be written to at one time. 这与将文件写入磁盘相同,只是将文件拆分为两个线程并不意味着它会更快,因为磁盘只能一次写入。 You might actually see a slower response time. 您实际上可能会看到较慢的响应时间。

You either have to superimpose a protocol on a single socket to identify what data is part of what file, or use multiple sockets so that you know where each file begins and ends. 您要么必须在单个套接字上叠加一个协议以识别哪些数据是哪个文件的一部分,要么使用多个套接字,以便知道每个文件的开始和结束位置。

Even with multiple sockets, you have to have start/end markers if you want to reuse the same socket for a new file without socket open/close housekeeping. 即使要使用多个套接字,如果要在没有套接字打开/关闭内务处理的情况下将同一套接字重新用于新文件,也必须具有开始/结束标记。

Why can't you use FTP? 为什么不能使用FTP?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM