我有一个Server类,它从客户端类接收.txt文件。
我的问题:我的服务器只接收第一个.txt文件,但之后客户端无法再发送,我怎样才能转换我的服务器类,以便服务器始终会收听新的文件?
这是服务器:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string rd;
byte[] b1;
string v;
int m=20;//number of byts
TcpListener list;
TcpClient client;
int port = 8100;//5050
int port1 = 8100;//5055
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
private void button1_Click(object sender, EventArgs e)//browse button
{
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
// while (true)
//try
// {
list = new TcpListener(localAddr, port1);
list.Start();
Thread incoming_connection = new Thread(ic);
incoming_connection.Start();
/*
}catch(Exception exc)
{
Console.Write(exc);
break;
}*/
}
}
private void ic()
{
client = list.AcceptTcpClient();
Stream s = client.GetStream();
b1 = new byte[m];
s.Read(b1,0, b1.Length);
MessageBox.Show("pathh "+textBox1.Text);
File.WriteAllBytes(textBox1.Text+"\\flag.txt", b1);// the left side us the name of the written file
//list.Stop();
//client.Close();
// label1.Text = "File Received......";
}
private void Form2_Load(object sender, EventArgs e)
{
list = new TcpListener(localAddr, port);
// TcpListener list = new TcpListener(port);
list.Start();
TcpClient client = list.AcceptTcpClient();
MessageBox.Show("Client trying to connect");
StreamReader sr = new StreamReader(client.GetStream());
rd = sr.ReadLine();
v = rd.Substring(rd.LastIndexOf('.') + 1);
m = int.Parse(v);
// list.Stop();
// client.Close();
}
}
答案 0 :(得分:0)
首先,您需要有人发送文字,有人接收文字
让我们从Sender
开始,让我们称之为Server
public class Server
{
//This is where the receiver connection will be stored
public TcpClient ClientConnection { get; set; }
public int Port { get; set; }
public string Host { get; set; }
public TcpListener Listener;
public Server(int port,string host)
{
this.Port = port;
this.Host = host;
}
public void Start()
{
this.Listener = new TcpListener(IPAddress.Parse(Host), Port);
TryConnect();
}
public void TryConnect()
{
//You can use thread
Task.Factory.StartNew(AcceptTheClientConnection, TaskCreationOptions.LongRunning);
}
public void AcceptTheClientConnection()
{
ClientConnection = this.Listener.AcceptTcpClient();
}
public void SendText(string text)
{
if (ClientConnection != null)
{
try
{
var buffer = System.Text.Encoding.Default.GetBytes(text);
ClientConnection.Client.Send(buffer, SocketFlags.None);
}
catch(Exception e)
{
ClientConnection = null;
TryConnect();
}
}
else throw new InvalidOperationException("You must connect to client first");
}
}
现在Receiver
是TcpClient
,此Receiver
将通过向其提供Sender
IP地址和端口来打开连接。成功连接到Receiver
后,Sender
将运行两个线程。第一个线程将继续侦听新文件,将接收到的文件缓冲区添加到队列中。第二个将处理这些缓冲区,在这里你可以放置自己的逻辑。
public class Client
{
public int SenderPort { get; set; }
public byte[] Buffer { get; set; }
public string SenderHost { get; set; }
public TcpClient SenderConnection;
public Queue<byte[]> ReceivedTextFiles;
public Client(int senderPort, string senderHost)
{
this.SenderPort = senderPort;
this.SenderHost = senderHost;
ReceivedTextFiles = new Queue<byte[]>();
}
public Task Connect()
{
return Task.Factory.StartNew(() =>
{
SenderConnection = new TcpClient();
SenderConnection.Connect(SenderHost, SenderPort);
Thread t = new Thread(Recieve);
Thread t2 = new Thread(ProcessTextFiles);
t.Start();
t2.Start();
});
}
public void Recieve()
{
while (true)
{
Thread.Sleep(500);
if (SenderConnection.Available > 0)
{
lock (Buffer)
{
Buffer = new byte[SenderConnection.Available];
int receivedBytes = SenderConnection.Client.Receive(Buffer);
if (receivedBytes > 0)
{
lock (ReceivedTextFiles)
{
ReceivedTextFiles.Enqueue(Buffer);
Buffer = null;
}
}
}
}
}
}
public void ProcessTextFiles()
{
while (true)
{
byte[] textFile = null;
lock (ReceivedTextFiles)
{
//We have buffers to process, get one, and remove it from the queue
if (ReceivedTextFiles.Count > 0)
{
textFile = ReceivedTextFiles.Dequeue();
}
}
//Process the buffer
var textFileContent = System.Text.Encoding.Default.GetString(textFile);
//Do whatever you want
Thread.Sleep(1500);
}
}
}
这是套接字背后的一般概念,以及如何在网络中发送和接收数据。请记住,此解决方案是根据您的目的量身定制的,只接受一个连接。这不是最好的解决方案,但是由于您的要求;我试着让它变得尽可能简单。另请注意,您可以使用Threads
或Tasks
这取决于具体情况。我会让你选择根据需要消费这两个课程的人。您可以编辑这两个课程。