因此,當服務器發送小於時16384字節然後客戶端接收所有沒有問題的數據。 但是,一旦服務器發送更多的數據,客戶端會收到奇怪的數量,比如6140.它並不總是這樣做,但它大部分時間都是這樣,但它經常這樣做。它很少收到完整的16384字節。C#套接字:客戶端在接收大緩衝區時沒有收到所有字節
起初我以爲連接花了很長時間才能發送全部數據,所以我將接收超時設置爲30秒(30000毫秒)。 這並沒有解決任何問題。每次我收到數據時,我都會使用一個新的字節數組,以便它不會被另一個BeginRecieve()
覆蓋。
我能想到的唯一的事情是硬件(計算機)無法在內存中保存這些大量的字節,因此會截斷緩衝區。 我有很多的代碼,但是這是事物的基礎:
Server代碼(只是一些吧):
private void RecieveCallBack(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
try
{
int len = client.EndReceive(ar);
byte[] tempBuffer = new byte[len];
Array.Copy(buffer, tempBuffer, len);
object RequestObject = GetRequestObject(tempBuffer); // just deserializes the buffer
byte[] response = GetResponseFromObject(RequestObject, client); // creates a buffer to return to the client
client.BeginSend(response, 0, response.Length, SocketFlags.None, new AsyncCallback(SendCallBack), client);
}
catch (Exception)
{
Program.Log("Client disconnected");
client.Close();
clientSockets.Remove(client);
Program.UpdateClientCount(clientSockets.Count);
}
}
private void SendCallBack(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
int sent = client.EndSend(ar);
Program.Log(sent); // log shows that server sent 16384 bytes
try
{
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), client);
}
catch (Exception e)
{
Program.Log(e.Message);
}
}
客戶端代碼(只是一些吧):
static void SendRequest(object obj)
{
byte[] buffer = SerializeObject(obj);
try
{
serverSockect.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), null);
}
catch // the send failed
{
serverSockect.Close();
ConnectedToServer = false;
}
}
static Queue<byte[]> buffers = new Queue<byte[]>();
static private void SendCallBack(IAsyncResult ar)
{
serverSockect.EndSend(ar);
try
{
// Create a new buffer for each new BeginRecieve.
// If one global buffer was used, then it might get overwritten by
// a second request when the first request hasn't yet been completed.
byte[] buffer = new byte[16384];
buffers.Enqueue(buffer);
serverSockect.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);
}
catch // the recieve failed
{
serverSockect.Close();
ConnectedToServer = false;
}
}
static private void RecieveCallBack(IAsyncResult ar)
{
byte[] buffer = buffers.Dequeue();
int len = serverSockect.EndReceive(ar); // len is usually some weird number
byte[] tempBuffer = new byte[len];
Array.Copy(buffer, tempBuffer, len);
object returnObj = GetResponseObject(tempBuffer);
HandleResponse(returnObj);
}
聽起來就像你只是得到1包,然後繼續前進,而不是等待其餘的 – BugFinder
這聽起來像普通的數據包碎片;你有沒有檢查其餘的數據是否到達下一個數據包? 「ReceiveCallBack」之後,您是否嘗試繼續閱讀並不清楚。在使用TCP時,您絕不應該依賴於您發送它的相同作品中的數據。它提供的只是* stream *(當被使用時)將以正確的順序爲您提供所有正確的數據。 –