Question

Using C# in .NET 4.5 in Visual Studio 2012 Ult on Win7 x64.

I’m trying to make a server transmit files via the System.Net.Sockets.Socket.SendFile(string filename) method and a client to receive it. The client appends received bytes to the end of the file it creates to reconstruct the sent file on its side. This all works – at least for basic text files.

When I try sending an *.exe file, the received *.exe doesn’t work. Opening both the source *.exe and client-side copy in Notepad++, it appears that the file is correct except that some of the weird-looking characters aren’t correct. My question is how do I fix this?

Since the server code is really just sending the file using Socket.SendFile(string filename) with no other relevant options available, I’m assuming that the client is the problem.

On the client side:

private void ListenAndReport(Socket socket)
{
    EndPoint remoteEndPoint = socket.RemoteEndPoint;
    ReceiveObject obj = new ReceiveObject(socket);
    socket.BeginReceive(obj.buffer, 0, packetSize, SocketFlags.None, new AsyncCallback(ReceiveFromListen), obj);
}
private void ReceiveFromListen(IAsyncResult ar)
{
    ReceiveObject obj = (ReceiveObject)ar.AsyncState;  //ReceiveObject just holds a byte[packetSize] buffer and a Socket

    string received = Encoding.UTF8.GetString(obj.buffer);
    WriteToFile(received);

    obj.socket.EndReceive(ar); //!!! necessary?  Doesn't seem to make a difference.
    ListenAndReport(obj.socket);
}
private void WriteToFile(string text)
{
    fileStream.Write(text);
    fileStream.Flush();
}

My guess is that the encoding in string received = Encoding.UTF8.GetString(obj.buffer); is incorrect, but I’ve tried all of the Encoding.something options, and none of them have correctly transmitted the file.

Alternatively, maybe the file writer, System.IO.TextWriter fileStream = File.AppendText(string filename);, is the problem?

Était-ce utile?

La solution

This is the problem:

string received = Encoding.UTF8.GetString(obj.buffer);

Why are you doing this? It's not text. You should be writing a byte array to the file, not a string.

Additionally, you should be using the return value of EndReceive to know how much data you've read:

int bytesRead = obj.socket.EndReceive(ar);
fileStream.Write(obj.buffer, 0, bytesRead);

(fileStream should be an actual stream, not a TextWriter.)

This will work for text files as well - if you treat text as binary, you end up with the same content at the other end, which you can still read as text. If you treat binary data as text, you end up with a mess of corrupted data...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top