полученные данные отличаются от данных, передаваемых через точный сокет - PullRequest
1 голос
/ 12 августа 2011

Я пытаюсь отправить файл с клиента на сервер, поэтому я загружаю файл в байтовый массив на стороне клиента и отправляю его на сервер с помощью метода send (), но полученный массивотличается от размера отправляемого массива. Интересно, это проблема протокола (но я использую протокол tcp, обеспечивающий обнаружение ошибок):

Код клиента:

IPAddress ipAddress = new IPAddress(ip);
IPEndPoint ipEnd = new IPEndPoint(ipAddress, 5656);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

FileStream fl = File.Open("pos.xls",FileMode.Open);
byte[] fileData = ReadFully(fl);
fl.Close();  

byte[] clientData = new byte[ fileData.Length];
fileData.CopyTo(clientData,0);

curMsg = "Connection to server ...";
clientSock.Connect(ipEnd);

curMsg = "File sending...";
clientSock.Send(clientData);

curMsg = "Disconnecting...";
clientSock.Close();
curMsg = "File transferred."; 

Код сервера

curMsg = "Starting...";
sock.Listen(100);

curMsg = "Running and waiting to receive file.";
byte[] clientData = new byte[1024 * 5000];
while (true)
{
    Socket clientSock = sock.Accept();

    clientData = new byte[1024 * 5000];

    int receivedBytesLen = clientSock.Receive(clientData);
    curMsg = "Receiving data...";

    FileStream fz = writeFully(clientData);
    fz.Close();
    curMsg = "Saving file...";

1 Ответ

1 голос
/ 12 августа 2011

У вас есть определенный clientData = new byte[1024 * 5000]; - и вы тогда не используете receivedBytesLen. Я не могу вспомнить, будет ли эта перегрузка Receive читать столько, сколько она может до EOF , или просто "некоторые или EOF" (последнее - поведение Stream.Read), но вы необходимо проверить и использовать receivedBytesLen.

IMO, подход с фиксированным буфером по своей сути несовершенен, поскольку он также не справляется с слишком большими входами. Лично я бы использовал NetworkStream здесь; тогда весь ваш код становится:

using(var fz = File.Create(path)) {
    networkStream.CopyTo(fz);
}

Другим распространенным подходом здесь является отправка ожидаемого размера в качестве префикса к данным; Таким образом, вы можете проверить, что у вас есть необходимые данные. Лично я не использовал бы эту информацию для создания буфера правильного размера в памяти, хотя это все еще не разрешает файлы эпического размера (однако Stream делает).

...