萌新请教个问题,Winform程序作客户端连接多个服务端进行通讯,C# Socket 也是刚学,没找到合适的书或是资料,看了好多博客写了些,但是一直不能用,想请大佬给看看,提些问题或者建议,感谢的😁
public partial class Form1 : MaterialForm
{
#region 已知信息存有以下信息的DataTable表
//dt表里存的是服务端的IP、端口号、还有发送的内容
DataTable dt_ServerInfo = new DataTable();
#endregion
#region 变量声明
private Dictionary<string, Socket> socketClients = new Dictionary<string, Socket>() { }; //客户端套接字集合
byte[] dataSend = new byte[500];
byte[] ReceiveByte = new byte[1024];
#endregion
#region 线程委托等实例
Thread SendThr = null;
#endregion
public Form1()
{
InitializeComponent();
GenerateDataTable(); //生成dt表结构和内容
CreateSocketConnection(); //创建Socket和建立连接
}
#region 自定义函数
private void CreateSocketConnection()
{
int countOfServers = dt_ServerInfo.Rows.Count;
for (int i = 0; i < countOfServers; i++)
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(dt_ServerInfo.Rows[i]["serverIP"].ToString()),int.Parse(dt_ServerInfo.Rows[i]["serverPort"].ToString()));
serverSocket.BeginConnect(serverEndPoint, new AsyncCallback(ConnectCallBack), serverSocket);
}
}
private void ConnectCallBack(IAsyncResult asyncResult)
{
Socket client = (Socket)asyncResult.AsyncState; //客户端套接字
try
{
client.EndConnect(asyncResult);
socketClients.Add(client.RemoteEndPoint.ToString(), client);
}
catch (Exception) //客户端开启后未连接,自动重连
{
IPEndPoint temppoint = (IPEndPoint)client.RemoteEndPoint;
client.BeginConnect(temppoint, ConnectCallBack, client);
}
}
private void SendThread()
{
while (socketClients.Count() > 0)
{
foreach (var item in socketClients)
{
string serverInfo = item.Key.ToString();
//string tst = $"ServerIp = '{serverInfo.Split(':')[0]}' And ServerPort = '{serverInfo.Split(':')[1]}' ";
DataRow[] drs = dt_ServerInfo.Select($"ServerIp = '{serverInfo.Split(':')[0]}' And ServerPort = '{serverInfo.Split(':')[1]}'");
byte[] sendByte = hexStringToByteArray(drs[0]["Command"].ToString());
item.Value.BeginSend(sendByte, 0, sendByte.Length, SocketFlags.None, new AsyncCallback(SendCallback), item.Value);
}
}
}
private void SendCallback(IAsyncResult asyncResult)
{
Socket client = (Socket)asyncResult.AsyncState; //客户端套接字
try
{
client.EndSend(asyncResult);
client.BeginReceive(ReceiveByte, 0, ReceiveByte.Length, SocketFlags.None, new AsyncCallback(AsyncReceiveCall), client);
}
catch (Exception) //当客户端无法发送命令时,自动断开连接并进行重连
{
IPEndPoint temppoint = (IPEndPoint)client.RemoteEndPoint;
socketClients[temppoint.ToString()].Close();
client.BeginConnect(temppoint, ConnectCallBack, client);
socketClients.Remove(temppoint.ToString());
}
}
private void AsyncReceiveCall(IAsyncResult asyncResult)
{
Socket client = (Socket)asyncResult.AsyncState; //客户端套接字
int bytesRead = client.EndReceive(asyncResult);
MessageBox.Show(ReceiveByte.ToString());
}
1.Dictionary<string, Socket> 可能会导致线程不安全的问题,使用 ConcurrentDictionary<string, Socket> 代替 Dictionary<string, Socket> 来确保线程安全。
2.当前的处理是在发生任何异常时进行自动重连,但这可能会导致无限次的重连尝试。改为对特定的异常类型进行处理,并在重试次数达到一定限制后停止重连。
3.SendThread() 中的 foreach 循环可能会导致性能问题【尚未找到更好的方法】
serverSocket.BeginConnect(serverEndPoint, new AsyncCallback(ConnectCallBack), serverSocket);
这个方法的参数为啥有serverSocket,你随便定义一个空的object对象放进去,看看有没有返回值
在回调里我需要用到它所以放进去了
https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket?view=net-7.0
– zhusunxiang 1年前