C# socket 包含断线重连功能的TCP客户端 具有发送失败缓存,等重连后继续发送
时间: 2024-09-26 11:08:08 浏览: 30
在C#中,为了创建一个具备断线重连和发送失败缓存功能的TCP客户端,你可以使用System.Net.Sockets命名空间下的TcpClient类,并结合Socket类的一些特性。以下是一个简单的示例:
```csharp
using System;
using System.Net;
using System.IO;
public class ReconnectableClient
{
private TcpClient client;
private Socket socket;
private Queue<string> sendQueue = new Queue<string>();
private const int BufferSize = 1024;
private bool isConnected = false;
public void Connect(string ipAddress, int port)
{
while (!isConnected)
{
try
{
client = new TcpClient(ipAddress, port);
socket = client.GetSocketAsyncStateObject();
socket.ReceiveBufferSize = BufferSize;
socket.SendBufferSize = BufferSize;
socket.BeginConnect(ipAddress, port, ConnectCallback, socket);
isConnected = true;
}
catch (Exception ex)
{
Console.WriteLine($"Connection failed: {ex.Message}. Retrying in 5 seconds...");
Thread.Sleep(5000); // 休眠5秒再尝试连接
}
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
socket.EndConnect(ar);
// 开始接收数据并处理发送队列
StartReceiving();
}
catch (Exception ex)
{
Console.WriteLine($"Error during connection: {ex.Message}");
CloseConnection();
}
}
private void StartReceiving()
{
NetworkStream stream = client.GetStream();
stream.BeginRead(new byte[BufferSize], 0, BufferSize, ReadCallback, stream);
}
private void ReadCallback(IAsyncResult ar)
{
NetworkStream stream = (NetworkStream)ar.AsyncState;
int bytesRead = stream.EndRead(ar);
if (bytesRead > 0)
{
string message = Encoding.ASCII.GetString(stream.ReadBytes(bytesRead));
Console.WriteLine("Received: " + message);
// 如果有未发送的数据,开始发送
if (sendQueue.Count > 0)
{
SendMessage();
}
}
else
{
// 没有接收到数据,可能是断开连接,检查并重试
CheckAndRetrySend();
}
}
private void SendMessage()
{
string message = sendQueue.Dequeue();
byte[] data = Encoding.ASCII.GetBytes(message);
socket.Send(data, 0, data.Length);
}
private void CheckAndRetrySend()
{
if (client.Connected && !socket.Connected)
{
Console.WriteLine("Lost connection, attempting to reconnect...");
CloseConnection();
Connect();
}
else if (sendQueue.Count > 0)
{
SendMessage();
}
}
private void CloseConnection()
{
try
{
socket.Shutdown(SocketShutdown.Both);
client.Close();
isConnected = false;
}
catch (Exception ex)
{
Console.WriteLine($"Error closing connection: {ex.Message}");
}
}
// 添加到发送队列的方法
public void EnqueueMessage(string message)
{
sendQueue.Enqueue(message);
}
}
```
在这个示例中,`ReconnectableClient`类包含了连接、读取、发送以及重连的基本逻辑。如果发送失败,数据会被放入发送队列,待重连成功后再尝试发送。
阅读全文