我做了一個客戶端&服務器建立通過套接字TCP連接,我試圖通過套接字發送二進制數據,但我只能派出TXT或PDF文件,我沒有運氣exe文件,我使用fread和fseek來讀取文件並將其分割成緩衝區。當我讀取整個exe文件時,它會被成功發送,但是當我分割它時,它會被髮送損壞!通過TCP發送二進制文件插座Ç
我讀了一些關於套接字的書,但我仍然不太瞭解,並且有一些問題。
可以在一個send()中發送整個文件嗎?或者我應該繼續以小塊形式發送它?
此外,爲什麼EXE文件在我發送塊時被損壞?
謝謝! (C語言)
客戶端代碼:
int bufSize = 10000;
int sentBytes = 0;
FILE * pFile;
long remainingBytes;
char * buffer;
size_t result;
pFile = fopen ("D:\\file.exe" , "rb");
fseek (pFile , 0 , SEEK_END);
remainingBytes = ftell (pFile);
rewind (pFile);
int bufferSize = remainingBytes > bufSize ? bufSize : remainingBytes;
buffer = (char*) malloc (sizeof(char)*bufferSize);
send(Socket, (char*)&remainingBytes, 4, 0);
while(remainingBytes > 0)
{
fseek (pFile , sentBytes , SEEK_SET);
result = fread(buffer,1,bufferSize,pFile);
if(bufferSize < remainingBytes)
{
send(Socket, buffer, bufferSize, 0);
}
else
{
send(Socket, buffer, remainingBytes, 0);
bufferSize = remainingBytes;
}
remainingBytes -= bufferSize;
sentBytes += bufferSize;
}
服務器代碼(C#)
try
{
int bufferSize = 200;
int len = 0;
int receivedBytes = 0;
int remainingBytes = len;
byte[] length = new byte[4];
//byte[] imgBuf = new byte[bufferSize];
int current = 0;
List<byte[]> coming = new List<byte[]>();
sockets[number].Receive(length,4,0);
len = BitConverter.ToInt32(length, 0);
remainingBytes = len;
bufferSize = len < bufferSize ? len : bufferSize;
while(receivedBytes < len)
{
if (remainingBytes > bufferSize)
{
coming.Add(new byte[bufferSize]);
//imgBuf = new byte[bufferSize];
sockets[number].Receive(coming[current], bufferSize, 0);
}
else
{
coming.Add(new byte[remainingBytes]);
//imgBuf = new byte[remainingBytes];
sockets[number].Receive(coming[current], remainingBytes, 0);
bufferSize = remainingBytes;
}
remainingBytes -= bufferSize;
receivedBytes += bufferSize;
current++;
//Array.Clear(imgBuf, 0, imgBuf.Length);
}
using (var stream = new FileStream(@"C:\receivedFile.exe",FileMode.Create))
{
using (var binaryWriter = new BinaryWriter(stream))
{
foreach (byte[] buffer in coming)
{
binaryWriter.Write(buffer);
}
}
}
}
catch (Exception ex)
{ this.setText(ex.Message, textBox2); }
編輯:感謝您的幫助,我得到它的工作:)
try
{
int bufferSize = 1024 * 100;
int len = 0;
int receivedBytes = 0;
int remainingBytes = len;
int reached = 0;
byte[] length = new byte[4];
byte[] imgBuf = new byte[bufferSize];
int current = 0;
sockets[number].Receive(length,4,0);
len = BitConverter.ToInt32(length, 0);
remainingBytes = len;
bufferSize = len < bufferSize ? len : bufferSize;
imgBuf = new byte[len];
while (reached < len)
{
reached += sockets[number].Receive(imgBuf, receivedBytes, remainingBytes, 0);
remainingBytes = len - reached;
receivedBytes = reached;
current++;
//Array.Clear(imgBuf, 0, imgBuf.Length);
}
using (var stream = new FileStream(@"C:\putty.exe",FileMode.Create))
{
using (var binaryWriter = new BinaryWriter(stream))
{
binaryWriter.Write(imgBuf);
}
}
Array.Clear(imgBuf, 0, imgBuf.Length);
}
catch (Exception ex)
{ this.setText(ex.Message, textBox2); }
如果你從文件系統傳輸整個文件,你應該使用['的TransmitFile()'](http://msdn.microsoft.com/en-us/library/ms740565(VS.85)。 aspx)(如果在Windows上)或['sendfile()'](http://www.kernel.org/doc/man-pages/online/pages/man2/sendfile.2.html)(如果在Unix上) – millimoose
感謝您的回答,但正如我所提到的,當我發送整個文件時,我完全沒有問題。只有當我嘗試以大塊發送時纔會出現此問題。 –
我想說的是,不應該通過在內存中緩衝文件來從文件中發送文件,以便從性能的角度出發,無論文件是否在大塊中 - 使用其中一種函數會更高效。 – millimoose