1

c#を使用してファイルを転送しています。私はこのコードを使用しました。問題は、.txtファイルのような小さなファイルは正しく転送されますが、画像、ドキュメント、pdf、pptのような大きなファイルは転送されないことです。コードが正常に機能する場合もありますが、ほとんどの場合、転送するデータ量は少なくなります。

サーバーコード:

Socket clientSock = sock.Accept();

byte[] clientData = new byte[1024 * 50000];
int receivedBytesLen = clientSock.Receive(clientData);
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + "/" + fileName, FileMode.Append));
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
bWrite.Close();
clientSock.Close();

クライアントコード:

byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] fileData = File.ReadAllBytes(filePath + fileName);
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);
clientSock.Connect(ipEnd);
clientSock.Send(clientData);
clientSock.Close();

完全なコードは上記のリンクにあります。私もこの投稿を見ましたが、これは役に立ちません。

4

2 に答える 2

4

コードが正常に機能する場合もありますが、ほとんどの場合、転送するデータ量は少なくなります。

これがの性質でありSocket.Receive()、送信されるすべてのデータが常に返されるとは限りません。

Receive(clientData, 4, 0)最初に、を示すバイトを受信するために実行する必要があります。次に、バイトを受信するまでループでsize呼び出します。ただし、他のオーバーロードと同じくらい簡単に、予想されるバイト数よりも少ないバイト数を返す可能性があることに注意してください。したがって、ループでそれを呼び出す必要もあります。Receive(clientData)sizeReceive(buffer[], length, offset)

このようなもの:

// First receive the size
int sizeSize = 4; // Size of Int32 in bytes
int sizeOffset = 0;
var sizeBytes = new byte[sizeSize];
while (sizeOffset < sizeSize)
{
    sizeOffset += clientSocket.Receive(sizeBytes, sizeSize - sizeOffset, sizeOffset);
}

var size = BitConverter.ToInt32(sizeBytes, 0);

// Then receive the data
byte[] fileData = new byte[size];
byte[] clientData = new byte[8192];
int totalBytes = 0;

while (totalBytes < size)
{
    // This may return anything between 0 and 8192, even if not all sent data has been received yet. It may be in a buffer somewhere, waiting to be picked up. Check for 0, since that's when the client disconnects.
    int bytesReceived = clientSocket.Receive(clientData);

    // You now have received a chunk of data of bytesReceived length. Append it into the fileData array.
    Buffer.BlockCopy(clientData, 0, fileData, totalBytes, bytesReceived);

    totalBytes += bytesReceived;
}
于 2012-08-10T16:46:12.227 に答える
0

CodeCasterがこれは100%正しくテストされていると答えたSocket.Receive(), it doesn't always return all data that gets sent to it.が、ファイルサイズを送信する次のステップが機能しないため、簡単で正しい解決策を見つけました。

Socket.Receive()メソッドは、受信したデータがコピーされるバイト配列を受け取り、受信したバイト数を返します。したがって、受信したバイトが0になるまで簡単にループできます。

byte[] tempData = new byte[1024 * 5000];

BinaryWriter bWrite = null;
int bytes_received;
int fileNamelength = 0;
bool isFirstPacket = true;

do
{
    bytes_received = clientSock.Receive(tempData);
    if(isFirstPacket)
    {
        isFirstPacket = false;
        int fileNameLen = BitConverter.ToInt32(tempData, 0);
        string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

        bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append))
        bWrite.Write(tempData, 4 + fileNameLength, bytes_received - 4 - fileNamelength);
    }
    else
        bWrite.Write(tempData, 0, bytes_received);
}
while (bytes_received != 0);
于 2012-08-14T18:20:18.660 に答える