[英]Error after connection restored Socket C#
我正在將文件分塊上傳到服務器。 如果你暫時斷開客戶端和服務器之間的連接,然后再恢復,服務器在嘗試從客戶端接收數據時會拋出錯誤:
嘗試建立連接未成功,因為在要求的時間內未從另一台計算機收到所需的響應,或者由於來自已連接計算機的錯誤響應而終止了已建立的連接
這發生在以下情況:如果我向服務器發送另一個塊並等待服務器的響應,則服務器此時處理請求,將響應發送給客戶端並等待下一個請求。 如果在向服務器發出請求后終止連接,並在 15 秒后恢復連接,則會出現錯誤。
從客戶端發送代碼的塊:
chunk = reader.ReadBytes(chunkSize);
bytesToRead -= chunkSize;
var packet = packetService.CreatePacket(new ServerPacket
{
Command = CommandsNames.UploadDataCommand,
ClientId = clientId,
Payload = uploadingService.GetUploadDataPayload(
chunk,
uploadingHash),
PayloadParts = new List<int>
{
Encoding.Unicode.GetByteCount(uploadingHash),
chunk.Length
}
});
await dataTransitService.SendDataAsync(_socket, packet);
var response = await dataTransitService
.ReadDataAsync(
_socket,
chunkSize,
p => packetService.ParsePacket(p));
SendDataAsync 方法:
public async Task SendDataAsync(
Socket socket,
IEnumerable<byte> data)
{
if (data != null && data.Any())
{
await socket.SendAsync(
new ArraySegment<byte>(data.ToArray()),
SocketFlags.None);
}
}
ReadDataAsync 方法:
public async Task<T> ReadDataAsync<T>(
Socket socket,
int chunkSize,
Func<IEnumerable<byte>, T> parsePacket)
{
var data = new ArraySegment<byte>(new byte[chunkSize]);
var receivedPacket = new List<byte>();
do
{
var bytes = await socket.ReceiveAsync(data, SocketFlags.None);
if (data.Array != null)
{
receivedPacket.AddRange(data.Array);
}
}
while (socket.Available > 0);
return parsePacket(receivedPacket);
}
客戶端套接字配置:
var (port, address) = (
_configurationSection["port"],
_configurationSection["address"]);
var ipPoint = new IPEndPoint(
IPAddress.Parse(address),
Int32.Parse(port));
socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
服務器套接字配置:
var section = _configuration.GetSection("listener");
var (address, port) = (section["address"], section["port"]);
var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var ipPoint = new IPEndPoint(IPAddress.Parse(address), Int32.Parse(port));
try
{
listenSocket.Bind(ipPoint);
listenSocket.Listen(20);
Console.WriteLine("Waiting for connections...");
var socket = listenSocket.Accept();
await _serverProcess.ProcessAsync(socket, StopServer);
如果在向服務器發出請求后終止連接,並在 15 秒后恢復連接,則會出現錯誤。
如果您拔下網線, Windows 通過該 NIC 告訴 sockets 他們已斷開連接。 否則(假設您的電纜仍然插入,但其間的電纜、交換機或路由器停止工作),您需要在該插座上發送或接收,以便它檢測到它已斷開連接。
一旦斷開連接,套接字將無法恢復。 您需要檢測此狀態,啟動新連接並告訴您的服務器您要繼續先前的傳輸。 我們不知道您的協議是否理解這一點。
另外: IEnumerable<byte> data
, data.Any()
, new ArraySegment<byte>(data.ToArray())
- 為什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.