连接恢复后出错 Socket C#
Error after connection restored Socket C#
我正在将文件分块上传到服务器。如果你断开客户端和服务器之间的连接一段时间,然后恢复,服务器在尝试从客户端接收数据时抛出错误:
An attempt to establish a connection was unsuccessful because the
desired response was not received from another computer within the
required time, or an already established connection was terminated due
to an incorrect response from an already connected computer
在以下情况下会发生这种情况:
如果我向服务器发送另一个块并等待服务器的响应,此时服务器处理请求,将响应发送给客户端并等待下一个请求。如果在向服务器发出请求后连接终止,并在 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);
If, after a request to the server, the connection is terminated, and after 15 seconds, it is restored, an error appears.
如果拔掉网线,Windows tells sockets over that NIC that they're disconnected。否则(假设您的电缆仍然插入,但电缆、交换机或路由器之间的电缆停止工作),您需要在该插座上发送或接收,以便它检测到它已断开连接。
参见 How to check if a socket is connected/disconnected in C#?。
套接字一旦断开,就无法恢复。你需要检测这个状态,开始一个新的连接并告诉你的服务器你想继续之前的传输。我们不知道您的协议是否理解这一点。
另外:IEnumerable<byte> data
、data.Any()
、new ArraySegment<byte>(data.ToArray())
- 为什么?
我正在将文件分块上传到服务器。如果你断开客户端和服务器之间的连接一段时间,然后恢复,服务器在尝试从客户端接收数据时抛出错误:
An attempt to establish a connection was unsuccessful because the desired response was not received from another computer within the required time, or an already established connection was terminated due to an incorrect response from an already connected computer
在以下情况下会发生这种情况: 如果我向服务器发送另一个块并等待服务器的响应,此时服务器处理请求,将响应发送给客户端并等待下一个请求。如果在向服务器发出请求后连接终止,并在 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);
If, after a request to the server, the connection is terminated, and after 15 seconds, it is restored, an error appears.
如果拔掉网线,Windows tells sockets over that NIC that they're disconnected。否则(假设您的电缆仍然插入,但电缆、交换机或路由器之间的电缆停止工作),您需要在该插座上发送或接收,以便它检测到它已断开连接。
参见 How to check if a socket is connected/disconnected in C#?。
套接字一旦断开,就无法恢复。你需要检测这个状态,开始一个新的连接并告诉你的服务器你想继续之前的传输。我们不知道您的协议是否理解这一点。
另外:IEnumerable<byte> data
、data.Any()
、new ArraySegment<byte>(data.ToArray())
- 为什么?