试图创建一个将接收多个文件的服务器,但它总是在接收到 1 个文件后停止

Trying to create a server that will receive more than 1 file, but it always stops after receiving 1 file

我正在尝试创建一个服务器来接收来自客户端的文件,现在它正在工作,但不是我想要的方式。我希望它的工作方式是:
1. 启动服务器
2. 从客户端#1
接收文件 3. 将一些其他文件发送回客户端 #1
4. 从客户端#1
接收另一个文件 依此类推,直到客户端停止连接。
现在服务器正在这样做:
1. 启动服务器
2. 从客户端#1
接收文件 3.(假设回信给客户端,但我还没有添加)
4.(此时客户端发送第二个文件,但服务器没有收到)
这是我在客户端的第 4 步中遇到的错误:

System.Net.Sockets.SocketException was unhandled
  HResult = -2147467259
  Message = was unable to make a connection because the target machine actively rejected it 192.168.1.11:5442
  Source = System
  ErrorCode = 10061
  NativeErrorCode = 10061
  StackTrace:
       at System.Net.Sockets.Socket.DoConnect (EndPoint endPointSnapshot, SocketAddress socketAddress)
       at System.Net.Sockets.Socket.Connect (EndPoint remoteEP)
       at System.Net.Sockets.TcpClient.Connect (IPEndPoint remoteEP)
       at ClientTest2.Program.Main (String [] args) in c: \ Users \ Shaked \ Documents \ Visual Studio 2012 \ Projects \ ClientTest2 \ ClientTest2 \ Program.cs: line 19
       at System.AppDomain._nExecuteAssembly (RuntimeAssembly assembly, String [] args)
       at System.AppDomain.ExecuteAssembly (String assemblyFile, Evidence assemblySecurity, String [] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly ()
       at System.Threading.ThreadHelper.ThreadStart_Context (Object state)
       at System.Threading.ExecutionContext.RunInternal (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run (ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart ()
  InnerException:

服务器端没有错误(没有运行时错误,但我认为代码有问题)。 这是服务器代码(注意:它是一个 windows 表单应用程序)

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace XO
{
    public partial class MultiPlayerLobby : Form
    {
        public MultiPlayerLobby()
        {
            InitializeComponent();
        }
        public static string LocalIPAddress()
        {
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    localIP = ip.ToString();
                    break;
                }
            }
            return localIP;
        }
        private void StartMultiPlayerGame(string player2Name)
        {
            MessageBox.Show(player2Name); //It gets the 1st string from the file, but not the 2nd file.
            //this.Close();
        }
        public string GetIP()
        {
            string externalIP = "";
            try
            {
                externalIP = (new WebClient()).DownloadString("http://checkip.dyndns.org/");
                externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")).Matches(externalIP)[0].ToString();
            }
            catch { return "Error getting ip adress."; }
            return externalIP;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            StartServerWorker.RunWorkerAsync();
            StartServerButton.Hide();
            LoadingGif.Size = new System.Drawing.Size(LoadingGif.Size.Width, LoadingGif.Size.Height);
            LoadingGif.BackgroundImageLayout = ImageLayout.Center;
            LoadingGif.Image = Properties.Resources.LoadingGif;
            ExitButton.Size = new System.Drawing.Size(ExitButton.Width + StartServerButton.Size.Width + 15, ExitButton.Size.Height);
        }
        private void StartServerWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            try
            {
                TcpListener tcpServer = new TcpListener(IPAddress.Parse(LocalIPAddress()), 5442);
                tcpServer.Start();
                Action serverStarted = () => StatusTextBox.AppendText("Server started");
                StatusTextBox.Invoke(serverStarted);
                TcpClient client = tcpServer.AcceptTcpClient();
                Action clientConnected = () => StatusTextBox.AppendText(Environment.NewLine + ("Client connection accepted from " + client.Client.RemoteEndPoint + "."));
                StatusTextBox.Invoke(clientConnected);
                using (StreamWriter sw = new StreamWriter(Application.StartupPath + @"File.txt"))
                {
                    byte[] buffer = new byte[1500];
                    int bytesRead = 1;
                    while (bytesRead > 0)
                    {
                        bytesRead = client.GetStream().Read(buffer, 0, 1500);
                        Action startedReadingData = () => { StatusTextBox.AppendText("started reading data from client " + client.Client.RemoteEndPoint); };
                        if (bytesRead == 0)
                        {
                            break;
                        }
                        sw.BaseStream.Write(buffer, 0, bytesRead);
                    }
                    Action readAllData = () => StatusTextBox.AppendText(Environment.NewLine + ("Read all Data from client."));
                    StatusTextBox.Invoke(readAllData);
                    sw.Close();
                }
                tcpServer.Stop();
                string player2Name;
                using (TextReader tr = new StreamReader(Application.StartupPath + @"File.txt"))
                {
                    player2Name = tr.ReadLine();
                    tr.Close();
                }
                Action finished = () => StartMultiPlayerGame(player2Name);
                StatusTextBox.Invoke(finished);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void MultiPlayerLobby_Load(object sender, EventArgs e)
        {
            BackgroundGePublicIP.RunWorkerAsync();
        }

        private void ExitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void MultiPlayerLobby_FormClosed(object sender, FormClosedEventArgs e)
        {
            //StartServerWorker.WorkerSupportsCancellation = true;
            //StartServerWorker.CancelAsync();
            //BackgroundGePublicIP.WorkerSupportsCancellation = true;
            //BackgroundGePublicIP.CancelAsync();
        }

        private void BackgroundGePublicIP_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            string publicIP = GetIP();
            Action updateIP = () => HostIPTextBox.Text = publicIP;
            HostIPTextBox.Invoke(updateIP);
        }
    }
}

这是客户端代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Windows.Forms;

namespace ClientTest2
{
    class Program
    {
        static void Main(string[] args)
        {
            StreamReader sr = new StreamReader(Application.StartupPath + @"\File");
            TcpClient tcpClient = new TcpClient();
            tcpClient.Connect(new IPEndPoint(IPAddress.Parse(LocalIPAddress()), 5442));
            byte[] buffer = new byte[1500];
            long bytesSent = 0;
            while (bytesSent < sr.BaseStream.Length)
            {
                int bytesRead = sr.BaseStream.Read(buffer, 0, 1500);
                tcpClient.GetStream().Write(buffer, 0, bytesRead);
                Console.WriteLine(bytesRead + " bytes sent.");
                bytesSent += bytesRead;
            }
            sr.Close();
            tcpClient.Close();
            Console.WriteLine("finished");
            Console.ReadLine();
        }
        public static string LocalIPAddress()
        {
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    localIP = ip.ToString();
                    break;
                }
            }
            return localIP;
        }
    }
}

(代码显示仅发送了一个文件,但我启动了服务器,然后启动了客户端,在服务器收到第一个文件后,我关闭客户端并再次打开它,以便它再次发送文件,但是在此时服务器出于某种原因拒绝了客户端) 我不太擅长网络套接字,所以如果我做了一些愚蠢的事情,请对我宽容:(

据我所知,您当前的代码在 StartServerWorker_DoWork() 函数中遗漏了一个 while() 循环。

目前你刚刚开始监听,获取文件,甚至关闭它,难怪你没有从客户端获取第二个文件。

有关基本 TcpListener class 用法,请参阅 this 示例。

另一方面,如果您要构建将使用大量 TCP/IP 的东西,您可以看看一些已经存在的解决方案,例如 jgauffin.framework.