我的服务器出现了黑洞(TcpClient,TcpListener)

4
我正在尝试构建一个服务器,用于接收客户端通过网络发送的文件。如果客户端决定一次只发送一个文件,那么没有问题,我会按照预期获得该文件,但是如果客户端尝试发送多个文件,我只会收到第一个文件。
以下是服务器代码: 我为每个连接的客户端使用一个线程。
public void ProcessClients()
{
    while (IsListening)
    {
        ClientHandler clientHandler = new ClientHandler(listener.AcceptTcpClient());
        Thread thread = new Thread(new ThreadStart(clientHandler.Process));
        thread.Start();
    }
}

以下代码是ClientHandler类的一部分。
public void Process()
{
    while (client.Connected)
    {
        using (MemoryStream memStream = new MemoryStream())
        {
            int read;
            while ((read = client.GetStream().Read(buffer, 0, buffer.Length)) > 0)
            {
                memStream.Write(buffer, 0, read);
            }

            if (memStream.Length > 0)
            {
                Packet receivedPacket = (Packet)Tools.Deserialize(memStream.ToArray());
                File.WriteAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), Guid.NewGuid() + receivedPacket.Filename), receivedPacket.Content);
            }
        }
    }
}

在第一次迭代中,我收到了第一个文件,但之后就没有收到任何东西。我尝试在每次迭代结束时使用Thread.Sleep(1000),但没有成功。

另一方面,我有这段代码(针对客户端)

.
.
client.Connect();
foreach (var oneFilename in fileList)
    client.Upload(oneFilename);
client.Disconnect();
.
.

上传方法:
public void Upload(string filename)
{
    FileInfo fileInfo = new FileInfo(filename);
    Packet packet = new Packet()
    {
        Filename = fileInfo.Name,
        Content = File.ReadAllBytes(filename)
    };

    byte[] serializedPacket = Tools.Serialize(packet);

    netStream.Write(serializedPacket, 0, serializedPacket.Length);
    netStream.Flush();
}

netStream(NetworkStream)在连接方法上打开,在断开连接时关闭。

黑洞在哪里?我能像我正在尝试的那样发送多个对象吗?

感谢您的时间。

1个回答

1
我猜测,如果客户端上传多个文件,您的循环在服务器端将整个流读取为单个文件。 那么“文件间的分隔符”在哪里? 服务器如何知道一个文件何时结束,另一个文件何时开始?

如果是这样,你会如何解释第一个文件已经成功传输的情况呢?第一次反序列化似乎工作正常。我说得对吗? - Tute
它的大小正确吗?还是客户端发送的所有文件的总大小?您如何验证收到的文件是否正确? - Brian
是的,它的大小正确,而且MD5值与第一个传输的文件也相同。这些文件是图像,所以很容易检查,但我还使用外部工具验证MD5校验和。 - Tute
你知道吗,我发现了这个网站(http://devblog.antongochev.net/2008/07/01/sending-data-via-tcp-using-tcpclient-and-tcplistener/),他使用“分隔符”正如你所说的那样,即使是使用序列化对象也是这样。我要试试看。 - Tute
没错,那就是问题所在。谢谢! - Tute

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接