views:

155

answers:

1

Hi,

I'm trying to build a server that will receive files sent by clients over a network. If the client decides to send one file at a time, there's no problem, I get the file as I expected, but if it tries to send more than one I only get the first one.

Here's the server code: I'm using one Thread per connected client

public void ProcessClients()
{
    while (IsListening)
    {
        ClientHandler clientHandler = new ClientHandler(listener.AcceptTcpClient());
        Thread thread = new Thread(new ThreadStart(clientHandler.Process));
        thread.Start();
    }
}

The following code is part of ClientHandler class

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);
            }
        }
    }
}

On the first iteration I get the first file sent, but after it I don't get anything. I've tried using a Thread.Sleep(1000) at the end of every iteration without any luck.

On the other side I have this code (for clients)

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

The method Upload:

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) is opened on Connect method, and closed on Disconnect.

Where's the black hole? Can I send multiple objects as I'm trying to do?

Thanks for your time.

+1  A: 

I am guessing that if clients upload multiple files, your loop is reading the whole stream as a single file on the server side. Where's the "delimiter between files"? How does the server know where one ends and another begins?

Brian
if that were the case, how would you explain the first file being successfully transferred? The first deserialization seems to be working okay. Am I correct?
Matías
Is its size correct? Or is it the sum total size of all the files the client sent? How are you validating the file is received correctly?
Brian
yes, its size is correct, and the md5 is also the same as the first transferred file. The files are images, so it's pretty easy to check, but i'm also using an external tool to verify the md5 checksum.
Matías
You know, I've found this other site (http://devblog.antongochev.net/2008/07/01/sending-data-via-tcp-using-tcpclient-and-tcplistener/) and he uses a "delimiter" as you said, even with serialized objects. Gonna try that.
Matías
Yep, that was the problem. Thank you!.
Matías