我有一個將文件發送到服務器的客戶端應用程序。問題是,在客戶端部分文件被正確讀取,我可以保存字節數組後,我讀它,並保存爲一個有效的JPG。但是,在服務器端,某些地方的數據被破壞。我所做的就是不斷向列表中添加所有傳入數據,直到客戶端關閉連接。TCP客戶端 - 數據僅在某些部分被損壞
我重疊發送客戶端和服務器/接收數據,正如你可以看到有地方數據不匹配的地方:http://s16.postimage.org/mtmm1hssl/corrupted_data.png
我不明白,這怎麼可能,我使用的是大緩衝區和圖像相當小,所以即使服務器在一個「塊」中接收到圖像,數據仍然被破壞。
任何想法爲什麼會發生這種情況?
UPDATE:
客戶端:
我獲取的圖像與HttpWebRequest的:
List<byte> test_buffer = new List<byte>();
using (Stream MyResponseStream = hwresponse.GetResponseStream())
{
byte[] MyBuffer = new byte[4096];
int BytesRead;
while (0 < (BytesRead = MyResponseStream.Read(MyBuffer, 0, MyBuffer.Length)))
{
for (int i = 0; i < BytesRead; i++)
{
test_buffer.Add(MyBuffer[i]); // just for testing
}
TCP_R.SendBytes(MyBuffer); // send data back to server
}
}
TCP_R.Close(); // tell server that we're done sending data
TCP_R是處理所有的TCP東西類(連接到服務器/發送數據)
這是TCP_R.SendBytes函數:
public void SendBytes(Byte[] data)
{
try
{
if (m_clientSocket != null)
{
m_clientSocket.Send(data);
}
}
catch (SocketException se)
{
log("send_bytes err: " + se.Message);
}
}
通知我以前test_buffer收集所有的字節是否被正確接收的一切來驗證。如果我使用此代碼:
MemoryStream ms = new MemoryStream(test_buffer.ToArray());
Image returnImage = Image.FromStream(ms);
returnImage.Save("image.jpg");
圖像已成功創建。所以我假設客戶端正確地發送數據。
服務器端:
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState; // cast
int iRx = 0;
iRx = socketData.m_currentSocket.EndReceive(asyn);
char[] chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?!
int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
for (int s = 0; s < charLen; s++)
{
RESPONSE_DATA.Add(socketData.dataBuffer[s]); // Collect response data
}
WaitForData(socketData.m_currentSocket, socketData.socket_id, REQUEST_INDEX_ID);
}
}
catch (ObjectDisposedException)
{
}
catch (SocketException se)
{
}
}
UPDATE2:
我使用OnDataReceived功能和REQUEST_RESPONSE這是List<byte>
建立的所有數據收集數據 看來,這些生產線造成問題:
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); // CAN THIS BE CAUSING THE PROBLEM!?!
int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
如何在不使用解碼器的情況下將數據提取到socketData.dataBuffer中?
解決方案: 雖然我是直接從DataBuffer中,讀「d.GetChars(socketData.dataBuffer ..」線不知何故搞砸了緩衝區,爲此我被搞砸了我的數據仍然需要使用則GetChars太閱讀包作爲字符串的第一部分,所以我只是改變:
int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
到:
byte[] tmp_a = new byte[socketData.dataBuffer.Length];
tmp_a = socketData.dataBuffer;
int charLen = d.GetChars(tmp_a, 0, iRx, chars, 0);
而現在一切工作順利進行。顯然不知何故直接調用緩衝區getChars影響緩衝區。
向我們展示一些代碼。如果你遺漏了所有的細節,你不能指望我們回答這個問題。 – usr 2012-03-02 16:02:53
我懷疑你的代碼在客戶端或服務器上有問題。不幸的是,您沒有向我們展示客戶端或服務器代碼,這使得很難說明... – 2012-03-02 16:03:07
需要查看您的代碼...發送和接收。 – 2012-03-02 16:03:32