1

私は tcp クライアントを持っています - サーバーの実装は、同じプログラムで、異なるバックグラウンド ワーカー スレッドで実行されています。複数のコンピューターにこのプログラムのインスタンスが存在するため、相互にファイルを送受信できます。ネットワークストリームを使用してコンピューター間でファイルを順番に送信できますが、コンピューターAからBに複数のファイルを同時に送信するにはどうすればよいですか.

1 つの接続 ( socket ) で複数のファイルを送信することは問題ありませんが、クライアントにデータを送信する複数のネットワーク ストリームがあると、クライアントはデータのどのチャンクがどのファイルから離れているかわかりません。

クライアントがサーバーに 2 回接続し (「ランダム」/未使用のポートが接続に割り当てられているため、異なるポートで)、各接続に独自のストリームがあり、2 つのファイルを同じ場所で送信できるようにすることは可能でしょうか?同時?

お時間とご尽力いただきありがとうございます。

4

5 に答える 5

5

クライアントは確かにサーバーに複数回接続する可能性があります-そしておそらくそうすべきです。

ただし、同じサーバーポートを指定することもできます。サーバー側で別のローカルポートが割り当てられますが、クライアントはそのことを知る必要はありません。(Webサーバーについて考えてみてください。多くのクライアントがすべて同時にポート80に接続します。)

もちろん、個別のクライアント側ポートも自動的に割り当てられます。基本的に、接続が相互に干渉することはありません。

于 2010-11-29T16:41:15.587 に答える
3

非同期クライアントとサーバー ソケットを使用する必要があります。基本的に、受信と送信を使用する代わりに、BeginRecieve、BeginSend、BeginConnect、BeginAccept を使用します。そうすれば、スレッド化が行われます。各接続をワーカー スレッドに含めることはお勧めできません。このようにして、新しいリクエストはそれぞれ同時に (非同期的に) 処理されます。送信したファイルの最初の数バイトを使用して、ファイルに関するデータを保存することもできます。以下の例。もちろん、以下の数値 (1,2,3..) は、Bitconverter.GetBytes(String var) を呼び出した文字列ファイル名になります。お役に立てれば。maxpfc@gmail.com (スカイプ)

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

以下は、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());
}
}
于 2012-02-05T15:29:25.390 に答える
1

クライアントがサーバーに2回接続し(「ランダム」/未使用のポートが接続に割り当てられているため、異なるポートで)、各接続に独自のストリームがあり、2つのファイルをで送信できるようにすることは可能でしょうか?同時?

はい; これは、ネットワークプロトコルが通常どのように機能するかです。サーバー側で新しいポート番号を選択する必要はありません。固定のポート番号でリッスンしている場合でも、そのポートへの接続は分離されたままになります。

たとえば、www.stackoverflow.comのウェブサーバーは常にポート80でリッスンしますが、あなたと私はウェブブラウザから接続でき、接続が混同されることはありません。

于 2010-11-29T16:41:20.380 に答える
1

あなたはそれをすることができます、しかし私は利益を見ません。各接続がラインのどこかで抑制されない限り、基本的にI/O操作の2倍のオーバーヘッドが発生します。

これは、ファイルをディスクに書き込むのと同じです。ディスクを2つのスレッドに分割したからといって、ディスクに一度にしか書き込むことができないため、高速になるとは限りません。実際には、応答時間が遅くなる場合があります。

于 2010-11-29T16:42:22.417 に答える
0

単一のソケットにプロトコルを重ねて、どのデータがどのファイルの一部であるかを識別するか、複数のソケットを使用して各ファイルの開始位置と終了位置を把握する必要があります。

複数のソケットがあっても、ソケットのオープン/クローズのハウスキーピングなしで新しいファイルに同じソケットを再利用したい場合は、開始/終了マーカーが必要です。

なぜFTPが使えないのですか?

于 2010-11-29T16:40:57.533 に答える