首页 新闻 会员 周边

C# Socket 客户端 逻辑思路 【小白提问】

0
悬赏园豆:50 [已解决问题] 解决于 2023-03-13 15:34

萌新请教个问题,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());
        }


MonoiF的主页 MonoiF | 菜鸟二级 | 园豆:264
提问于:2023-02-17 09:08
< >
分享
最佳答案
0

1.Dictionary<string, Socket> 可能会导致线程不安全的问题,使用 ConcurrentDictionary<string, Socket> 代替 Dictionary<string, Socket> 来确保线程安全。
2.当前的处理是在发生任何异常时进行自动重连,但这可能会导致无限次的重连尝试。改为对特定的异常类型进行处理,并在重试次数达到一定限制后停止重连。
3.SendThread() 中的 foreach 循环可能会导致性能问题【尚未找到更好的方法】

MonoiF | 菜鸟二级 |园豆:264 | 2023-02-18 09:22
其他回答(1)
0

serverSocket.BeginConnect(serverEndPoint, new AsyncCallback(ConnectCallBack), serverSocket);
这个方法的参数为啥有serverSocket,你随便定义一个空的object对象放进去,看看有没有返回值

收获园豆:50
国产小品牌 | 园豆:199 (初学一级) | 2023-02-17 17:05

在回调里我需要用到它所以放进去了

支持(0) 反对(0) MonoiF | 园豆:264 (菜鸟二级) | 2023-02-17 17:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册