Dateiübertragung mit Hilfe von sockets (C#) - empfangene Datei enthält nicht die vollständigen Daten
Ich erstellt einen server und einen client für Datei-übertragung per socket-Verbindung.
Das problem, das ich bin vor ist, dass die empfangene Datei, wenn Ihre Größe 8KB, ist unvollständig.
Wenn Sie stehen vor diesem Problem, können Sie mich auf, herauszufinden, was ich falsch mache (auf dem server /client-Seite)?
Sind hier sowohl Methoden:
Client:
#region FILE TRANSFER USING C#.NET SOCKET - CLIENT
class FTClient
{
public static string curMsg_client = "Idle";
public static void SendFile(string fileName)
{
try
{
//IPAddress[] ipAddress = Dns.GetHostAddresses("localhost");
//IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5656);
string IpAddressString = "192.168.1.102";
IPEndPoint ipEnd_client = new IPEndPoint(IPAddress.Parse(IpAddressString), 5656);
Socket clientSock_client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileName = fileName.Replace("\\", "/");
while (fileName.IndexOf("/") > -1)
{
filePath += fileName.Substring(0, fileName.IndexOf("/") + 1);
fileName = fileName.Substring(fileName.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName);
if (fileNameByte.Length > 5000 * 1024)
{
curMsg_client = "File size is more than 5Mb, please try with small file.";
return;
}
curMsg_client = "Buffering ...";
string fullPath = filePath + fileName;
byte[] fileData = File.ReadAllBytes(fullPath);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
curMsg_client = "Connection to server ...";
clientSock_client.Connect(ipEnd_client);
curMsg_client = "File sending...";
clientSock_client.Send(clientData, 0, clientData.Length, 0);
curMsg_client = "Disconnecting...";
clientSock_client.Close();
curMsg_client = "File [" + fullPath + "] transferred.";
}
catch (Exception ex)
{
if (ex.Message == "No connection could be made because the target machine actively refused it")
curMsg_client = "File Sending fail. Because server not running.";
else
curMsg_client = "File Sending fail." + ex.Message;
}
}
}
#endregion
und Server:
#region FILE TRANSFER USING C#.NET SOCKET - SERVER
class FTServer
{
IPEndPoint ipEnd_server;
Socket sock_server;
public FTServer()
{
//make IP end point to accept any IP address with port 5656
//these values will be altered depending on ******* (and/or other ImportSystem)
//this was initially coded, but threw a SocketException on sock.Bind(ipEnd) {Only one usage of each socket address (protocol/network addres/port) is normally permitted}
//ipEnd = new IPEndPoint(IPAddress.Any, 5656);
//
//I'll set it like this (giving the IP through a string)
string IpAddressString = "192.168.1.102";
ipEnd_server = new IPEndPoint(IPAddress.Parse(IpAddressString), 5656);
//
//creating new socket object with protocol type and transfer data type
sock_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
//bind end point with newly created socket
sock_server.Bind(ipEnd_server);
}
public static string receivedPath = @"C:\Users\Adrian.Constantin\Desktop\Simulare_Forder_Import\";
public static string curMsg_server = "Stopped!";
public void StartServer()
{
try
{
curMsg_server = "Starting...";
sock_server.Listen(100);
curMsg_server = "Running and waiting to receive file.";
Socket clientSock = sock_server.Accept();
byte[] clientData = new byte[512000];
int receivedBytesLen = clientSock.Receive(clientData, SocketFlags.None);
clientSock.ReceiveBufferSize = 8192;
curMsg_server = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.UTF8.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + "/" + fileName, FileMode.OpenOrCreate)); ;
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
curMsg_server = "Saving file...";
bWrite.Close();
clientSock.Close();
curMsg_server = "Received and Archived file [" + fileName + "]; Server stopped.";
}
catch (SocketException ex)
{
curMsg_server = "File Receving error.";
MessageBox.Show(String.Format("{0} Error cide: {1}", ex.Message, ex.ErrorCode));
}
}
}
#endregion
edit: 24.08.2012 (ich habe es geschafft, herauszufinden, die Ausgabe und die server funktionieren)
Vollständige code für die server ist :
SERVER:
#region FILE TRANSFER USING C#.NET SOCKET - SERVER
class FTServer
{
IPEndPoint ipEnd_server;
Socket sock_server;
public FTServer()
{
string IpAddressString = "192.168.1.102";
ipEnd_server = new IPEndPoint(IPAddress.Parse(IpAddressString), 5656);
sock_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock_server.Bind(ipEnd_server);
}
public static string receivedPath = @"C:\";
public static string curMsg_server = "Stopped!";
public void StartServer()
{
try
{
curMsg_server = "Starting...";
sock_server.Listen(100);
curMsg_server = "Running and waiting to receive file.";
Socket clientSock = sock_server.Accept();
clientSock.ReceiveBufferSize = 16384;
byte[] clientData = new byte[1024 * 50000];
int receivedBytesLen = clientSock.Receive(clientData, clientData.Length, 0);
curMsg_server = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.UTF8.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append));
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
while (receivedBytesLen > 0)
{
receivedBytesLen = clientSock.Receive(clientData, clientData.Length, 0);
if (receivedBytesLen == 0)
{
bWrite.Close();
}
else
{
bWrite.Write(clientData, 0, receivedBytesLen);
}
}
curMsg_server = "Saving file...";
bWrite.Close();
clientSock.Close();
curMsg_server = "Received and Archived file [" + fileName + "] (" + (receivedBytesLen - 4 - fileNameLen) + " bytes received); Server stopped.";
}
catch (SocketException ex)
{
curMsg_server = "File Receving error.";
MessageBox.Show(String.Format("{0} Error code: {1}", ex.Message, ex.ErrorCode));
}
}
}
#endregion
InformationsquelleAutor Adi Constantin | 2012-08-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie gefallen in die klassische Falle der socket-Nutzung. Dieser ist so alt wie die Idee von sockets entwickelt an der Berkeley..
Sehen Sie, Sie haben nicht die Dokumentation Lesen 🙂
Sehen die http://msdn.microsoft.com/en-us/library/ms145160.aspx zum Beispiel - was ist der Rückgabewert?
Senden und Empfangen von Methoden sind nicht verpflichtet, die eigentlich alle senden/empfangen der Daten, die Sie zur Verfügung gestellt haben. Das ist, warum Sie beide geben ein 'int', die beschreibt, wie viele senden/empfangen tatsächlich. Dieses design gehalten wird, weil das system die internen Puffer sind begrenzt. Wenn man ein array von 999GB gesendet werden, wie Sie Ihre Netzwerk-Karte gespeichert werden, bevor es tatsächlich sendet?
Sehen Sie das Verhalten für 8KB Schwelle, wahrscheinlich, weil das ist die Größe der intenal Puffer, oder vielleicht die maximale Größe eines TCP-Netzwerk-Paket.. ich weiß nicht wie groß Sie waren, aber es ist etwas, dass rund.
Senden und empfangen Ihre Daten poperly, müssen Sie irgendeine Art von Schleife, zum Beispiel, in der form vereinfacht:
- und recv - ähnlich.
InformationsquelleAutor quetzalcoatl
Vom MSDN:
Es nicht* garantieren zu Lesen, alles in einem Rutsch; es liest, was es kann bis zu das maximum (die Größe des Puffers in Ihrem Fall). Beim Lesen von alle - stream, müssen Sie in der Regel haben eine Lese - /Empfangs-loop. In deinem Fall würde ich sagen, dass der Puffer ist stark überdimensioniert, und das sollten Sie Lesen Sie die "length" - Byte manuell, dann nur noch eine Lese - /Empfangs-Schleife über eine kleine - Puffer (sagen, 4096 bytes) der Datei handling. Sie brauchen nicht einen 512KB Puffer.
Einen Klassiker Lesen/Empfangen-Schleife wäre:
heh, ziemlich wahr, vor allem mit UDP und gemischtes Paket bestellen 🙂
InformationsquelleAutor Marc Gravell
Müssen Sie die Verzögerung vor jedem Versand-Methoden über 200 ms ist, weil Ihre Empfangs-Puffer wird überschrieben durch die eingehenden Daten.
Beispiel:
InformationsquelleAutor user10074350